Re: __block __weak - am I doing this right?
Re: __block __weak - am I doing this right?
- Subject: Re: __block __weak - am I doing this right?
- From: Matt Neuburg <email@hidden>
- Date: Thu, 16 Feb 2012 12:42:06 -0800
On Feb 16, 2012, at 12:05 PM, Greg Parker wrote:
> On Feb 16, 2012, at 8:22 AM, Matt Neuburg <email@hidden> wrote:
>> On Wed, 15 Feb 2012 16:20:50 -0800, Greg Parker <email@hidden> said:
>>>
>>> Are you using GC or ARC? I think this is safe with GC but not safe with ARC, but I'm not an expert in the NSNotificationCenter machinery.
>>
>> ARC, but I don't see how it might be unsafe. I sure *hope* it isn't, because that's what the __weak is for. You need that because if your observer doesn't vanish in good order, neither will +self+, because the observer retains +self+, not just while registered with the notification center but for as long as it lives (by way of the block, I presume). *That* is something I *do* understand, having spent many hours watching the retain counts at work.
>
> The question is, who retains the observer? The __block __weak variable does not, because it's weak. NSNotificationCenter does not, as I understand it.
It does, actually; thanks for pressing me on this point.
That's why the easiest pattern under ARC for preventing a retain cycle in general (that is, where you - a view controller, say - hang on to a reference to the observer for a long time, like from viewWillAppear: to viewWillDisappear:) is to store it in a __weak ivar. When you unregister the observer (which you can do, because you have a reference to it in the ivar), the notification center releases it, it goes out of existence, the __weak ivar is automatically nilified, and (most important) the observer releases you, preventing a retain cycle.
Of course you could also solve the problem with a __strong ivar and nilify the ivar yourself after you unregister. But you don't have to, because the notification center retains the observer from the get-go. If it didn't, the __weak ivar would be nil when you need to unregister - and it isn't.
I've documented this (after a lot of experimentation - and did I mention "thank you, Instruments"???) here:
http://www.apeth.com/iOSBook/ch12.html#_retain_cycles_and_weak_references
Naturally if you have any thoughts I would be *very* happy to hear them. m.
PS Oh, and if you'd like to play with the various possibilities, there's no need to write any code: I have a downloadable example project that demonstrates all of them:
<https://github.com/mattneub/Programming-iOS-4-Book-Examples/blob/master/convertedToIOS5/p229NotificationLeaker/p229NotificationLeaker/FlipsideViewController.m>
Set the ivar to __weak and leave the #define set at 1. Run the project. Flip the view and flip it back (with Done) and watch the Console. You'll see that observer is good and that we dealloc successfully.
--
matt neuburg, phd = email@hidden, http://www.apeth.net/matt/
pantes anthropoi tou eidenai oregontai phusei
Programming iOS 5! http://shop.oreilly.com/product/0636920023562.do
RubyFrontier! http://www.apeth.com/RubyFrontierDocs/default.html
TidBITS, Mac news and reviews since 1990, http://www.tidbits.com
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden