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 10:58:25 -0700
> On May 2, 2016, at 10:38 AM, Steve Mills <email@hidden> wrote:
> I'm working on a project that's had to support older hardware/software until now, so we can *finally* convert to ARC. Since it's been almost a year since I've worked on anything that used ARC, I'm a little rusty on some of the stranger stuff, like __unsafe_retained. Here's a pared down hunk before converting to ARC:
>
> NSXMLElement* root = [NSXMLNode elementWithName:@"manifest" children:nil attributesWithDict:@{@"thing":@"stuff"}];
>
> __block NSXMLElement* rezes = [NSXMLNode elementWithName:@"resources"];
> __block NSXMLElement* rez;
>
> [root addChild:rezes];
>
> [indices enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL* stop) {
> rez = [NSXMLNode elementWithName:@"resource" children:nil attributesWithDict:@{@"identifier":item}];
> [rezes addChild:rez];
> [self _addQTIManifestResources:images addResourcesToNode:rezes];
> }];
>
> After using Edit->Convert->To Objective-C ARC, the 2nd line was changed to:
>
> __unsafe_unretained NSXMLElement* rezes = [NSXMLNode elementWithName:@"resources"];
>
> I've looked around, but can't find anything that explains why __unsafe_retained is needed AND why __block is NOT needed.
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.
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.
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