I am trying to grasp how I can recognize when a strong retain cycle is possible and requires me to use [weak/unowned self]
. I've been burned by unnecessarily using [weak/unowned self]
and the self was deallocated immediately before giving me a chance to use it.
For example, below is an async network call that refers to self
in the closure. Can a memory leak happen here since the network call is made without storing the call it self into a variable?
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) {
(data, response, error) in
self.data = data
)
Here's another example using the NSNotificationCenter, where a call can be made later asynchronously:
NSNotificationCenter.defaultCenter().addObserverForName(
UIApplicationSignificantTimeChangeNotification, object: nil, queue: nil) {
[unowned self] _ in
self.refresh()
}
My question is in what cases is a strong retain cycle possible? If I am making an asynchronous call or static call that references self in a closure, does that make it a candidate for [weak/unowned self]
? Thanks for shedding any light on this.
In a nutshell:
The retain cycle can happen in two cases.
Case 1:
When two instances hold a strong reference to each other. You have to solve this by marking one of them as weak.
Case 2: (Which is related to your questions)
If you assign a closure to a property of a class instance and the body of that closure captures the instance.
In your two examples, no need to use weak self at all as
NSNotificationCenter
norNSURLSession
are properties to your class instance. (Or in other meaning, you don't have strong references to them)Check this example where I have to use weak self:
I have a strong reference to
mm_drawerController
and I assign a closure to it right?. inside this closure I want to capture self. So the closure will have a strong reference to self !! which is a disaster. In that case you will have a retain cycle. To break this cycle, use weak self inside the closure.A retain cycle is a situation when two objects has a strong reference to each other.
You are working with static variables NSURLSession.sharedSession() & NSNotificationCenter.defaultCenter() and as you may remember:
https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/Singleton.html
Your "self" instance (like the others) doesn't have a strong reference to singletons objects and its closures too, that's why you don't have to worry about retain cycle in your case.
Check this great article for more details: https://digitalleaves.com/blog/2015/05/demystifying-retain-cycles-in-arc/