我有以下代码
- (NSString *)stringByEscapingXMLEntities;
{
NSString *result;
@autoreleasepool {
result = [self stringByReplacingOccurrencesOfString:@"&" withString:@"&"];
result = [result stringByReplacingOccurrencesOfString:@"\"" withString:@"""];
// ... lot of -stringByReplacingOccurrencesOfString: calls
result = [result stringByReplacingOccurrencesOfString:@" " withString:@" "];
}
return result;
}
我现在问自己如何将所有权result
转移出方法。在ARC之前,我会在退出autorelease块之前保留result
并在方法结束时自动释放它。
谢谢!
答案 0 :(得分:4)
有两种方法可以做到:
copyStringByEscapingXMLEntities
- copy
表示所有权转让,ARC会相应地创建代码。NS_RETURNS_RETAINED
附加到方法定义,如下所示:- (NSString *)stringByEscapingXMLEntities NS_RETURNS_RETAINED
。 编辑:正如'iljawascoding'提到的那样,除了优化之外,@autoreleasepool
没有必要保留 -
编辑2:请记住: ARC始终做正确的事。您尝试的所有内容(您的评论)都会生成完全相同的正确程序 - 尽管如果结果定义为__strong
,则缺少某些优化。
答案 1 :(得分:2)
完全摆脱自动释放。根据Apple的说法,ARC将在您的代码完成后使用“结果”中存储的临时实例自动插入必要的版本。在这里滚动自己的自动释放池没有任何好处。
答案 2 :(得分:2)
您发布的代码是正确的。任何崩溃都有不同的原因。
因为result
是自动释放范围之外的强引用,ARC负责在退出池时保持活动状态,并且确实如此。你不需要做任何特别的事情。
更具体地说,ARC生成与此相当的代码:
void *_arp = objc_autoreleasePoolPush();
temp1 = objc_retainAutoreleasedReturnValue([self stringByReplacingOccurrencesOfString:@"&" withString:@"&"]);
temp2 = objc_retainAutoreleasedReturnValue([temp1 stringByReplacingOccurrencesOfString:@"\"" withString:@"""]);
objc_release(temp1);
result = objc_retainAutoreleasedReturnValue([temp2 stringByReplacingOccurrencesOfString:@" " withString:@" "]);
objc_release(temp2);
// result is not released here
objc_autoreleasePoolPop(_arp);
return objc_autoreleaseReturnValue(result); // Result is returned autoreleased, or handed off to a matching objc_retainAutoreleasedReturnValue() in the caller.
请注意,临时变量由objc_retainAutoreleasedReturnValue
/ objc_release
对处理。由于objc_retainAutoreleasedReturnValue
和objc_retainAutoreleasedReturnValue
实现了运行时优化,这意味着临时值实际上会立即释放,而不会被放入自动释放池,如果 {{1}用ARC构建。我的猜测是,大多数系统框架还没有。
答案 3 :(得分:0)
为什么不在[[NSString alloc] initWithString:result]
范围关闭之前使用@autoreleasepool
?但为什么ARP首先在哪?