using @autoreleasepool in NSString category

Hi,


I'm using ARC. I created an NSString category and some of the methods returns autoreleased NSString itself. For example:


- (NSString *) replaceOneOccuranceOfString:(NSString *) str1 withString:(NSString *) str2

{

@autoreleasepool

{

// code to check range etc

.....

NSString *replacedStr = [self stringByReplacingCharactersInRange:[self rangeOfString:str1]

withString:str2];

return replacedStr;

.....

}

}


And in other cases, they use autoreleased strings, e.g.



- (BOOL) isSublingOf:(NSString *) path

{

@autoreleasepool

{

NSString *parent = [self stringByDeletingLastPathComponent];

NSString *parent1 = [path stringByDeletingLastPathComponent];

if([parent isEqualToString:parent1])

{

return YES;

}

return NO;

}

}


I wanted to clarify my understanding here. In both these cases, these auto-released will get drained at the return of the function and in the first method, the reciever will add refcount and will be added to it's own auto-released object ?

Replies

No. There is no API contract about methods returning autoreleased objects. The API contract is about methods transferring ownership to the caller, or not. The definitive discussion is here:


developer.apple.com/library/ios/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html


and you should always rely on that official documentation rather than anything anyone tells you, in (say) these forums.


— I'm not sure why you think your 2 cases are different, because none of the methods you refer to return a +1 ("ownership transferred to you") reference. They all return +0 references ("you must take ownership if you want to keep the objects alive").


— However, because you're using ARC, your code automatically takes care of the ownership, so you don't normally have to worry about it.


— As a matter of implementation detail, when a +0 reference is returned, it's kept alive (during the return) by one of two mechanisms:


a. it's autoreleased before returning, or


b. it's returned without being autoreleased, in technical violation of the memory management rules, because ARC can then skip an additional 'retain' after the return. (This keeps the object alive until you've done with it, without the normal overhead of an autorelease followed by a re-retain.)


The use of @autoreleasepool { … } in your code is not about following the memory mangement rules (ARC does that for you), but to let you force draining of the autorelease pool, preventing the buildup of autoreleased objects over the longer term.


You should not use @autoreleasepool { … } in either of the two examples you gave, but especially in the first one. You're returning a +0 reference, which means that either mechanism "a" or mechanism "b" must be used, after the autorelease pool is drained. IOW, you might be causing twice the autorelease overhead.


You should leave it to the caller to decide whether to use @autoreleasepool { … } or not. It's usually done only when methods are called in a tight loop.