Why my delegate = nil?

Hi!

I have protocol AllNotebookDelegate:

protocol AllNotebookDelegate: class {
    func passData(text: String,nameOfNotebook: String)
}

And also I have class AllNotebookCollectionVC with collectionView(didSelectRowAt:) method:

class AllNotebookCollectionViewController: UICollectionViewController {
    //MARK: - Variables
    var notebookItems: [NotebookItem] = []
    weak var delegate: AllNotebookDelegate?
    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let selectedItem = notebookItems[indexPath.item]
        delegate?.passData(text: selectedItem.text, nameOfNotebook: selectedItem.titleOfNotebook)
        
        // Present EditorVC
        let editorVC = storyboard!.instantiateViewController(withIdentifier: "editorVC")
        let navigationController = UINavigationController(rootViewController: editorVC)
        present(navigationController, animated: true, completion: nil)
    }
}

This is editorVC:

class EditorViewController: UIViewController {

    //MARK: - Variables & Outlets

    @IBOutlet weak var textView: UITextView!

    //MARK: - Private methods
    override func viewDidLoad() {
        super.viewDidLoad()
        let allNotebookVC = storyboard?.instantiateViewController(withIdentifier: "allNotebookVC") as! AllNotebookCollectionViewController
        textView.text = ""
        allNotebookVC.delegate = self
}

extension EditorViewController: AllNotebookDelegate {
    func passData(text: String, nameOfNotebook: String) {
        titleOfNavigationBar = nameOfNotebook
        textView.text = nameOfNotebook
    }




When I add a breakpoint at collectionView(cellForRowAt:) in AllNotebookVC debugger show me this:

collectionViewUICollectionView0x00007fee26878c00
indexPathIndexPath2 indices
selfScroll.AllNotebookCollectionViewController0x00007fee25c09b00
UIKit.UICollectionViewControllerUICollectionViewController
notebookItems[Scroll.NotebookItem]1 value
delegateAllNotebookDelegate?nilnone
selectedItemScroll.NotebookItem0x0000600003add100
titleOfNotebookString""
nameOfImageOfNotebookString"wallper"
textString""
editorVCScroll.EditorViewController0x00007fee25e0f580
UIKit.UIViewControllerUIViewController
textViewUITextView?nilnone
titleOfNavigationBarString""
navigationControllerUINavigationController0x00007fee27015200
UIKit.UIViewControllerUIViewController


So, why delegate = nil?

Replies

override func viewDidLoad() {  
        super.viewDidLoad()  
        let allNotebookVC = storyboard?.instantiateViewController(withIdentifier: "allNotebookVC") as! AllNotebookCollectionViewController  
        textView.text = ""  
        allNotebookVC.delegate = self  
} 

(Line 03.) You declare a block-loacal constant `allNotebookVC` and initialize it with a newly created instance of `AllNotebookCollectionViewController`.

(Line 05.) You set the delegate of the instance of `AllNotebookCollectionViewController` you have ceeated in Line 03.

(Line 06.) At the end of the block, the local constant `allNotebookVC` is released, the instance with delegate set is gone.


So you are setting the delegate of an instance which will be disposed very soon which cannot be reused.


To solve this issue, you may need to show the code or settings which explains how you are showing your `AllNotebookCollectionViewController`.


Generally, you should better set the delegate of view controllers just before showing it.

Following on OOPer post, you should probably:

- declare at the class level

var allNotebookVC : AllNotebookCollectionViewController?


remove declareation (delete let) in

let allNotebookVC = storyboard?.instantiateViewController(withIdentifier: "allNotebookVC") as! AllNotebookCollecti

AllNotebookCollectionViewController is starter screen of my app.

Then you should better re-consider which class to have delegate. Usually, you make secondary view controller have delegate.


Anyway, in your current code, you are setting delegate of a never shown instance of `AllNotebookCollectionViewController`, not the instance of starter screen of your app.