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 21:10:17 -0800
On Feb 16, 2012, at 4:16 PM, Greg Parker wrote:
> On Feb 16, 2012, at 12:57 PM, Matt Neuburg <email@hidden> wrote:
>> On Feb 16, 2012, at 12:45 PM, Greg Parker wrote:
>>> On Feb 16, 2012, at 12:42 PM, Matt Neuburg <email@hidden> wrote:
>>>> On Feb 16, 2012, at 12:05 PM, Greg Parker wrote:
>>>>>
>>>>> 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.
>>>
>>> The NSNotificationCenter documentation says:
>>> "Important: The notification center does not retain its observers…"
>>
>> We may be talking at cross purposes.
>>
>> If you register by saying addObserver:selector:name:object:, the notification center does not retain the observer object named in the first param.
>>
>> But if you register by saying addObserverForName:object:queue:usingBlock:, it returns an observer object, and the notification center *does* retain that observer.
>
> Aha. That's the part I didn't see, and it contradicts the "Important" note at the top of the NSNotificationCenter documentation. I'll file a documentation bug report.
>
> With that clarified, the example you posted should be fine.
>
>
> There's an alternative if you are using ARC and you know the notification will fire exactly once:
>
> // ARC required.
> __block id observer = [[NSNotificationCenter defaultCenter]
> addObserverForName:@"MyMandelbrotOperationFinished"
> object:op queue:[NSOperationQueue mainQueue]
> usingBlock:^(NSNotification *note) {
> MyMandelbrotOperation* op2 = note.object;
> // do stuff
> [[NSNotificationCenter defaultCenter] removeObserver:observer
> name:@"MyMandelbrotOperationFinished" object:op2];
> observer = nil;
> }];
>
> This version does not use __weak. Instead, the block object creates a retain cycle by retaining the observer via the __block variable. When the block object executes, it breaks the cycle by setting the __block variable to nil, releasing the observer.
>
> If you have a specific time that you can break the cycle, you can use this pattern. The pattern would fail if you didn't know when you could break the cycle (for example, if the block might run zero times).
Right, good point (several good points). Thanks again. m.
--
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