Objective c 如何使用ARC将所有权转移出@autoreleasepool
我有以下代码Objective c 如何使用ARC将所有权转移出@autoreleasepool,objective-c,ios,cocoa,automatic-ref-counting,autorelease,Objective C,Ios,Cocoa,Automatic Ref Counting,Autorelease,我有以下代码 - (NSString *)stringByEscapingXMLEntities; { NSString *result; @autoreleasepool { result = [self stringByReplacingOccurrencesOfString:@"&" withString:@"&"]; result = [result stringByReplacingOccurrencesOf
- (NSString *)stringByEscapingXMLEntities;
{
NSString *result;
@autoreleasepool {
result = [self stringByReplacingOccurrencesOfString:@"&" withString:@"&"];
result = [result stringByReplacingOccurrencesOfString:@"\"" withString:@"""];
// ... lot of -stringByReplacingOccurrencesOfString: calls
result = [result stringByReplacingOccurrencesOfString:@" " withString:@" "];
}
return result;
}
我现在问自己,如何将所有权结果
从方法中转移出去。在ARC之前,我会在退出自动释放块之前保留结果
,并在方法结束时返回自动释放的结果
谢谢 完全摆脱自动释放。根据苹果公司的说法,ARC将在您的代码处理完“result”中存储的临时实例后自动插入必要的版本。在这里滚动您自己的自动释放池没有任何好处。为什么不在
@autoreleasepool
范围关闭之前使用[[NSString alloc]initWithString:result]
?但是为什么要把ARP放在首位呢 有两种方法可以做到这一点:
- 将该方法重命名为类似于
,copyStringByEscapingXMLEntities
表示所有权转移,ARC会相应地创建代码copy
- 在标题中,将
附加到方法定义中,如下所示:NS\u返回\u保留的
-(NSString*)stringByEscapingXMLEntities NS\u返回\u保留的
编辑:正如“IljawasCodeing”所提到的那样,
@autoreleasepool
除了优化之外,不需要保留
编辑2:并记住:ARC总是做正确的事情。您尝试过的所有事情(您的评论)都会产生完全相同的正确程序——尽管如果结果被定义为
\uu strong
您发布的代码是正确的,则会缺少一些优化。任何撞车都有不同的原因
因为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\u retainaureleasedreturnvalue
/objc\u release
对处理的。由于运行时优化由objc\u retainustereleasedReturnValue
和objc\u retainustereleasedReturnValue
实现,这意味着如果-stringByReplacingOccurrencesOfString:
是使用ARC构建的,则临时值实际上将立即释放,而不会放入自动释放池。不过,我的猜测是,大多数系统框架还没有实现。以下是我迄今为止尝试过的:在自动释放池中返回;将结果定义为_u强,并使该方法返回一个保留对象;您在arc下还有自动释放池吗?您在那里的池不起作用吗?我原以为编译器知道result
是在池的作用域之外声明的,会添加必要的retain。在崩溃的Mac OS上进行测试。另外,我们假设自动释放池是必要的。这基本上就是我想完全理解为什么它不起作用的东西。这段代码对我来说很有用。我们能看看正在崩溃的代码吗?对于真正的问题,可能有更好的解决方案。如果经常调用该方法,并且希望确保临时对象已耗尽,则自动释放池可能有意义。但是有没有方法可以在不更改方法签名的情况下执行此操作?第二种方法,appendNS\u将返回\u NOT\u RETAINED
。方法名和签名保持不变——它只是一个属性。问题是编译器需要知道类和每个调用中的行为——唯一的方法是公共接口。没别的办法。对不起,刚才看到我的意思是NS\u返回\u保留
,而不是NS\u返回\u不保留
)这个答案是胡说八道。使该方法返回保留值并不影响ARC(正确)如何处理自动释放池范围外的转移。@Ahruman:问题清楚地表明:“我现在问自己,我将如何将所有权结果转移出该方法”。这就是答案。