With a NSNotificationCenter block, I have to use [unowned self] to avoid a strong reference cycle:
NSNotificationCenter.defaultCenter()
.addObserverForName(UIApplicationWillEnterForegroundNotification,
object: nil,
queue: nil,
usingBlock: { [unowned self] (notification : NSNotification!) -> Void in
self.add(123)
})
However, in UIView.animateWithDuration, I do not have to use [unowned self]:
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.someOutlet.alpha = 1.0
self.someMethod()
})
What's the difference?
The only difference between the animation block and the notification center block is that the animation block is extremely short-lived—it is executed immediately and then released.
In both cases, the blocks will capture self
; but only the NSNotificationCenter
code is problematic because the notification center will hold a reference to the block indefinitely, since the notification can happen at any time.
Note that this is different than a circular reference. A circular reference is often created by an object holding a reference to a block that captures self, like this:
self.myBlock = {
self.doSomething()
}
That circular reference means that self
will never be deallocated. The notification center isn't a circular reference (since self doesn't hold a reference to the notification center), it's just a regular reference that will be held until the observer is removed.