Swift协议代理函数未被调用问题求助(图书库开发场景)
Hey there! Let's walk through the most common reasons why your delegate method isn't firing when you add a book and navigate back to the table view controller. I've run into this exact issue a bunch of times, so here's what to check step by step:
First, make sure your protocol is properly defined for class types (since delegates need to be reference types), and your delegate property is marked weak to avoid retain cycles:
// In AddBookViewController protocol AddBookDelegate: class { func didAddBook(_ book: Book) } weak var delegate: AddBookDelegate?
If you forget the class modifier on the protocol or skip weak for the delegate property, you might run into unexpected behavior or memory leaks that break the delegate chain.
This is the most common mistake! When you push or present the AddBookViewController, you need to explicitly set its delegate to your table view controller.
If you're using storyboard segues, do this in prepare(for:sender:):
// In your BookListTableViewController override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard let addVC = segue.destination as? AddBookViewController else { return } addVC.delegate = self }
If you're creating the AddBookViewController programmatically, set the delegate right before presenting/pushing:
let addVC = AddBookViewController() addVC.delegate = self navigationController?.pushViewController(addVC, animated: true)
Double-check that your table view controller declares conformance to the AddBookDelegate protocol, and that the method signature matches exactly (no typos in parameter names or types):
// In BookListTableViewController class BookListTableViewController: UITableViewController, AddBookDelegate { // Your data source array var books: [Book] = [] // Delegate method implementation func didAddBook(_ book: Book) { // Add the new book to your data source and refresh the table books.append(book) tableView.reloadData() } // Rest of your table view code... }
Even a tiny mismatch (like writing didAddBook(book: Book) instead of didAddBook(_ book: Book)) will cause the method to not be called.
Make sure you're actually calling the delegate method before navigating back to the table view. Here's how the button tap handler should look:
// In AddBookViewController @IBAction func addButtonTapped(_ sender: UIButton) { // Validate input first guard let title = titleTextField.text?.trimmingCharacters(in: .whitespaces), !title.isEmpty, let author = authorTextField.text?.trimmingCharacters(in: .whitespaces), !author.isEmpty, let publisher = publisherTextField.text?.trimmingCharacters(in: .whitespaces), !publisher.isEmpty else { // Show an alert to the user if fields are empty let alert = UIAlertController(title: "Oops!", message: "Please fill in all book details.", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default)) present(alert, animated: true) return } // Create the Book object let newBook = Book(title: title, author: author, publisher: publisher) // Call the delegate method FIRST delegate?.didAddBook(newBook) // Then navigate back if let navController = navigationController { navController.popViewController(animated: true) } else { dismiss(animated: true) } }
If you navigate back before calling delegate?.didAddBook(newBook), the view controller might be deinitialized before the delegate method can fire.
Add a deinit method to your AddBookViewController to check if it's being released too early:
deinit { print("AddBookViewController deinitialized") }
If you see this print statement immediately after tapping the add button (before the delegate method should run), it means the controller is being deallocated prematurely. This usually happens if you didn't set the delegate correctly, or if there's an issue with your navigation flow.
Start with these checks—9 times out of 10, the problem is one of these common oversights. Let me know if you're still stuck after going through them!
内容的提问来源于stack exchange,提问作者J Duh

