• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Converting to ARC and blocks
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • Follow-Ups:
    • Re: Converting to ARC and blocks
      • From: Steve Mills <email@hidden>
References: 
 >Converting to ARC and blocks (From: Steve Mills <email@hidden>)

  • Prev by Date: Re: Converting to ARC and blocks
  • Next by Date: Re: Converting to ARC and blocks
  • Previous by thread: Converting to ARC and blocks
  • Next by thread: Re: Converting to ARC and blocks
  • Index(es):
    • Date
    • Thread