2

I have successfully implemented a closure in class to get filtered contacts from my phonebook but when I call this closure it creates a leak, I tested it in Xcode instrument tool.

See my implementation,

class CR: NSObject {

 func GetAllSBUser(handler:@escaping (Array<SBUserModel>?, Error?) -> ()) {
    CRBlock = handler

    if self.AllUSersModels.count>0 {
       self.CRBlock(self.AllUSersModels, nil)
    } else {
        self.CRBlock(nil, err)
    }}}

I use this method in another class, see my implementation.

I also have a global instance in my app delegate like this

let app = UIApplication.shared.delegate as! AppDelegate

class friendsVC: UIViewController, UITextFieldDelegate {

override func viewDidLoad() {
        super.viewDidLoad()

        self.app.cri?.AllSBFriends(handler: { (SBfriendsUIDs, error) in

            if error == nil{

                // Do something with list

            } else{ self.friendsCountLbl.text = "Friends \(0)" }
        })
    }
}

In class friendsVC, this method produces a leak. How can I remove it? Should I use [unowned self] or weak? [unowned self] or weak may create a crash in some special cases of retain cycle. Please suggest me, how to fix it.

Harendra Tiwari
  • 460
  • 5
  • 11

2 Answers2

2

You need to use weak modifier for closures where your will be using self

self.app.cri?.AllSBFriends(handler: { [weak self] (SBfriendsUIDs, error) in

        if error == nil{

            // Do something with list

        } else{ self?.friendsCountLbl.text = "Friends \(0)" }
    })
Reinier Melian
  • 20,519
  • 3
  • 38
  • 55
  • Thanks, @Reinier Melian for your answer. could you please explain why I should not use unowned? – Harendra Tiwari May 10 '18 at 10:23
  • @HarendraTiwari, basically you should use unowned only when your are really sure that this variable [self] will be not nil at the time that closure is executed, normally I use [weak self] all the time and check self nullability, check this answer for further information https://stackoverflow.com/questions/24320347/shall-we-always-use-unowned-self-inside-closure-in-swift – Reinier Melian May 10 '18 at 10:28
  • Great, Thank you – Harendra Tiwari May 10 '18 at 10:45
0

@Harendra,

As conveyed by @Reinier use the below code like below.

self.app.cri?.AllSBFriends(handler: { [weak self] (SBfriendsUIDs, error) in

    if error == nil{

        // Do something with list

    } else{ self?.friendsCountLbl.text = "Friends \(0)" }
})

IMP:- Also implementation inside CRBlock func should be inside @autoreleasepool{ //Implementation of CRBlock func }

CrazyPro007
  • 1,006
  • 9
  • 15