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 08:22:22 -0800
On Wed, 15 Feb 2012 16:20:50 -0800, Greg Parker <email@hidden> said:
>On Feb 15, 2012, at 12:58 PM, Matt Neuburg <email@hidden> wrote:
>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.
>Without __block, the block object snapshots the value of the observer variable when the block object is created. But in your code the block object is created before the call to -addObserverForName:..., and at that point the observer variable is not yet initialized. Boom.
>
>With __block, the block object always uses the current value of the observer variable. The variable is initialized before the block object actually executes, so everything works.
Thank you! (So, the fact that we are async is crucial to this working. I was missing *that* piece of the mental puzzle too, though of course I would not have used sync in any case.)
I feel this wasn't quite made clear by the WWDC videos and the docs. Perhaps it's in the latter and I missed it. This is not a criticism (I would never criticize the GCD/runtime people about how they explain GCD; au contraire, I think you guys are the best explainers associated with Apple), just a suggestion. A simple sentence would suffice: You can use the result of a call to a method that takes a block inside the block, but only if it is typed as __block (and only if the block is executed later).
The same issue came up again later the same day:
__block UIBackgroundTaskIdentifier bti = [[UIApplication sharedApplication]
beginBackgroundTaskWithExpirationHandler: ^{
[[UIApplication sharedApplication] endBackgroundTask:bti];
}];
Without __block, bti is invalid, and you won't find that out easily because it's unlikely that you'll actually expire. :) m.
--
matt neuburg, phd = email@hidden, <http://www.apeth.net/matt/>
A fool + a tool + an autorelease pool = cool!
Programming iOS 5! http://shop.oreilly.com/product/0636920023562.do
_______________________________________________
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