5

In my app I'm using delegates, so that I can read the data when ever it's ready.

I'm calling a delegate from two classes. Here is my code

protocol MyDelegate: class {
    func getData()
}

class MyDelegateCalss {

     weak var delegate: MyDelegate?    
     func loadData() {

        // doing some actions        

         if(self.delegate != nil){
            self.delegate!.getData!()
        }
    }
}

In one class I'm loading this method in tableview numberOfSections delegate method.

class A: UIViewController, MyDelegate {


    func somefunc(){
        let mydelegatecls : MyDelegateCalss = MyDelegateCalss()
        mydelegatecls.delegate = self
        mydelegatecls.loadData()
    }


    func getData(){
       // Doing some actions
    }
}

This method I'm loading from another calss.

class B: UIViewController, MyDelegate {


   open func testfunc(){

    let mydelegatecls : MyDelegateCalss = MyDelegateCalss()
      mydelegatecls.delegate = self
      mydelegatecls.loadData()
   }



    func getData(){
      // doing some other stuff    
    }

}



class C: UIViewController {

       func testfunc(){

        let b : B = B()
          b.testfunc()
       }
    }

Here from class A my delegate is working fine. and I'm able to see getData method is calling .

from Class B, the delegate becomes nil and unable to see getData method is called

If I make the delegate reference its working fine. But that will cause memory leak.

How can handle this case ?

  • Where do you have the first 3 lines in A and B? Are they simply put into the class just like in the code snippets? What happens if you move them to `viewDidLoad`? – Losiowaty Apr 26 '17 at 12:45
  • May I know what is the real use case of this scenario ? – CodeChanger Apr 26 '17 at 12:45
  • edited.. the 3 lines are in some methods.. Not in viewDidLoad @ Losiowaty –  Apr 26 '17 at 12:49
  • 1
    My use case is .. Im calling an Api and saving data to DB. I can call that API from different screens, based on requirement . so i have one class in which I'm proceeding the Api request and saving data to DB. After all DB querys .. Using delegate to inform my view controller that data is updated . Here I'm getting that issue. –  Apr 26 '17 at 12:50
  • 1
    Show how you call `testfunc` on `A` and `B`. – shallowThought Apr 26 '17 at 12:53

1 Answers1

5

Your delegate var is declared as weak. If nothing keep a strong reference on the object you assign as the delegate (implementing MyDelegate), your delegate will pass to nil as soon as the object is released (eg. the end of the scope where you instantiate it).

Some good read: https://cocoacasts.com/how-to-break-a-strong-reference-cycle/

Loos
  • 66
  • 4
  • It would be prudent to mention specifically where the object goes out of scope and gets released (i.e. at the end of `testFunc()`) and how to solve it (i.e. add a class variable to store `MyDelegateCalss`) – Losiowaty Apr 27 '17 at 05:12