Re: __bridge_transfer on a method return value

2012-05-10 Thread Quincey Morris
On May 9, 2012, at 23:07 , Roland King wrote:

 I'm using CFURLCreateStringByAddingPercentEscapes() because the NSString 
 version leaves '+' signs unescaped. If I used it directly in code I'd either 
 CFRelease it, or if assigned to an NSString, __bridge_transfer it. However I 
 want it as the return value of a method. So I wrote this
 
   +(NSString*)webEncodedString:(NSString *)string
   {
   CFStringRef retval = CFURLCreateStringByAddingPercentEscapes( 
 NULL, (__bridge CFStringRef)string, NULL, CFSTR( !*'();:@=+$,/?%#[] ), 
 kCFStringEncodingUTF8 );
   return( __bridge_transfer NSString*)retval;
   }
 
 My confusion comes from not knowing whether this function now returns an 
 object with a +1 refcount or not. If it does it needs to be renamed to have 
 new or copy etc in the method name, or annotated properly to show that. My 
 first thought was that yes the transfer means the return value has a +1 
 refcount. Then I wondered if the __bridge_transfer transfers ownership to 
 some temporary inside the method which will be released as it goes out of 
 scope and do the job so all retains/releases are balanced out and the return 
 value does not have an extra retain on it. I suppose if I wrote the same 
 thing like this it highlights the difference
 
   +(NSString*)webEncodedString:(NSString *)string
   {
   CFStringRef retval = CFURLCreateStringByAddingPercentEscapes( 
 NULL, (__bridge CFStringRef)string, NULL, CFSTR( !*'();:@=+$,/?%#[] ), 
 kCFStringEncodingUTF8 );
   NSString *temp = (__bridge_transfer)retval;
   return temp;
   }
 
 Here it would seem the ownership passes to temp, which goes out of scope at 
 the end of the method and would release, after I assume some 
 retains/autoreleases are done to ensure the object lives long enough to make 
 it back to the caller, but still balanced. 

You're correct that the two versions are equivalent at the point of return. I 
believe the balance sheet looks like this in the first case:

+1  assumed by the bridge transfer to have already happened
-1  from completing the expression containing the bridge transfer
+1  to the return expression result
-1  from returning

Thus the net retain count is 0, but the return statement ensures that the 
object survives at least until the caller has a chance to retain it. This might 
be via an autorelease, or may be something more optimal.

The balance sheet for the second case looks like this:

+1  assumed by the bridge transfer to have already happened
-1  from completing the expression containing the bridge transfer
+1  from the assignment to temp
+1  to the return expression result
-1  from temp going out of scope
-1  from returning

So the net is still 0.

This is all on the basis of:

http://clang.llvm.org/docs/AutomaticReferenceCounting.html

in sections 3.2.3, 3.2.4 and 4.2.

The only differences that calling this method 'newWebEncodedString' would make 
(AFAIK) are that the return value would never need to be autoreleased, the 
final release from the return statement wouldn't happen, and the caller would 
have slightly different code because of the guaranteed +1 retain count.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: __bridge_transfer on a method return value

2012-05-10 Thread Ken Thomases
On May 10, 2012, at 1:07 AM, Roland King wrote:

 My confusion comes from not knowing whether this function now returns an 
 object with a +1 refcount or not. If it does it needs to be renamed to have 
 new or copy etc in the method name, or annotated properly to show that.

I think you have this backward.  You are giving ownership over to ARC.  ARC 
decides what to do in part based on the method name.  You don't pick the method 
name to match the behavior you anticipate from ARC, ARC picks its behavior 
based on the name, which should reflect your chosen semantics.

Since your method name doesn't indicate that it returns ownership, ARC will 
autorelease the value.  [If the caller is also compiled with ARC, then it 
hardly matters.  It will decide how to behave also based on the method name and 
the two behaviors will complement each other (and, depending on optimizations, 
cancel out so that neither an autorelease nor a retain happens).  If the caller 
is MRC, then ARC autoreleasing the return value is, of course, important given 
your method name.]

Regards,
Ken


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: __bridge_transfer on a method return value

2012-05-10 Thread Roland King

On May 10, 2012, at 11:54 PM, Ken Thomases wrote:

 On May 10, 2012, at 1:07 AM, Roland King wrote:
 
 My confusion comes from not knowing whether this function now returns an 
 object with a +1 refcount or not. If it does it needs to be renamed to have 
 new or copy etc in the method name, or annotated properly to show that.
 
 I think you have this backward.  You are giving ownership over to ARC.  ARC 
 decides what to do in part based on the method name.  You don't pick the 
 method name to match the behavior you anticipate from ARC, ARC picks its 
 behavior based on the name, which should reflect your chosen semantics.
 
 Since your method name doesn't indicate that it returns ownership, ARC will 
 autorelease the value.  [If the caller is also compiled with ARC, then it 
 hardly matters.  It will decide how to behave also based on the method name 
 and the two behaviors will complement each other (and, depending on 
 optimizations, cancel out so that neither an autorelease nor a retain 
 happens).  If the caller is MRC, then ARC autoreleasing the return value is, 
 of course, important given your method name.]
 
 Regards,
 Ken
 

Nicely put Ken and thanks too to Quincey who said much the same thing. I'd 
gotten stuck thinking that I had to figure out ownership and be explicit about 
it to match the method instead of understanding I just need to tell ARC what 
semantics I want when an object moves from CoreFoundation to Cocoa and let it 
sort it out what to do later based on the name and attributes of the method, 
which of course other code, ARC and non-ARC will then interpret correctly. 

ARC continues to be a very well thought out framework which hasn't let me down 
yet. 

Now back to the keychain API on iOS .. possibly not quite as coherent. 

Thanks both, I'm much happier now. 
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: __bridge_transfer on a method return value

2012-05-10 Thread Greg Parker
On May 10, 2012, at 8:54 AM, Ken Thomases k...@codeweavers.com wrote:
 On May 10, 2012, at 1:07 AM, Roland King wrote:
 My confusion comes from not knowing whether this function now returns an 
 object with a +1 refcount or not. If it does it needs to be renamed to have 
 new or copy etc in the method name, or annotated properly to show that.
 
 I think you have this backward.  You are giving ownership over to ARC.  ARC 
 decides what to do in part based on the method name.  You don't pick the 
 method name to match the behavior you anticipate from ARC, ARC picks its 
 behavior based on the name, which should reflect your chosen semantics.
 
 Since your method name doesn't indicate that it returns ownership, ARC will 
 autorelease the value.  [If the caller is also compiled with ARC, then it 
 hardly matters.  It will decide how to behave also based on the method name 
 and the two behaviors will complement each other (and, depending on 
 optimizations, cancel out so that neither an autorelease nor a retain 
 happens).  If the caller is MRC, then ARC autoreleasing the return value is, 
 of course, important given your method name.]

This logic is clearer if you use the CFBridgingRetain() and CFBridgingRelease() 
functions instead of the __bridge_retained and __bridge_transfer casts:

+(NSString*)webEncodedString:(NSString *)string
{
CFStringRef retval = CFURLCreateStringByAddingPercentEscapes( 
NULL, (__bridge CFStringRef)string, NULL, CFSTR( !*'();:@=+$,/?%#[] ), 
kCFStringEncodingUTF8 );
return CFBridgingRelease(retval);
}

CFBridgingRelease() balances CFURLCreateString...(). Everything else is ARC's 
problem as usual.


-- 
Greg Parker gpar...@apple.com Runtime Wrangler



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com