Re: Converting to ARC and blocks
Re: Converting to ARC and blocks
- Subject: Re: Converting to ARC and blocks
- From: John McCall <email@hidden>
- Date: Mon, 02 May 2016 11:42:38 -0700
> On May 2, 2016, at 11:30 AM, Steve Mills <email@hidden> wrote:
>
> On May 02, 2016, at 12:58 PM, John McCall <email@hidden> wrote:
>
> > You don't have to declare something with __block just to use it in a block. __block specifically means that the variable will be captured *by reference* in the block, meaning that changes to the variable within the block are visible in the original scope and vice-versa. Without this, the block literal will capture the current value of the variable, and you will not be able to assign to it within the block.
>
> Ah yes, good point. My __block decoration on rezes might've been done in an earlier iteration of the code, where it really *was* allocated and assigned inside the block.
>
> > When blocks capture a value of ObjC pointer type like that, they retain it. That's not always desired, either for efficiency reasons or because it introduces retain cycles, and so __block is sometimes used in non-ARC code as a (very inefficient) way to prevent that retain. That doesn't work in ARC, because assigning to a __strong __block variable retains the new value, just like assigning to any other __strong variable. So the migrator tries to recognize __block variables that are being used that way (i.e. __block variables that are never modified) and instead declare them as __unsafe_unretained.
>
> So is the compiler/migrator recognizing here that rezes get added to the root object, then later used in various blocks (there are more than one, but I didn't show them) before finally going out of scope, so it's just being more efficient, rather than just letting its retain count get incremented when it's added to root, then decremented when rezes goes out of scope?
No. It's just recognizing that putting __block on rezes is otherwise pointless because you never assign to it, so it guesses that you might be trying to suppress a retain.
Now, maybe that's giving the programmer too much credit. :) But I think it's more reasonable to add __unsafe_unretained than to silently do nothing at the risk of introducing a retain cycle — for one, it's preserving the behavior of your code, and for another, it's much easier for programmers to statically see the explicit __unsafe_unretained and try to figure out if it's reasonable than for them to dynamically track down yet another retain cycle. Migrating to ARC is definitely *not* fire-and-forget! You really do need to look over the results and see whether they make sense.
John.
_______________________________________________
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