ARC“删除未使用的自动释放消息是不安全的”

时间:2012-02-25 18:05:19

标签: iphone objective-c ios automatic-ref-counting

转换到ARC时,我收到以下编译错误:"删除未使用的自动释放消息"是不安全的。

如果我只是删除autorelease消息,obj将在getAutoreleasedObj结束时立即释放,这将导致printObj崩溃。那么如何处理自动释放的对象,并将以下代码转换为ARC?

- (MyClass *) getAutoreleasedObj {
    MyClass *obj = [[MyClass alloc] init];
    [obj autorelease];
    return obj;
}

- (void) printObj {
NSLog(@"%@", [self getAutoreleasedObj];
}

6 个答案:

答案 0 :(得分:5)

您不必自动发布它,因为它是从函数返回的,ARC将隐式地将其__autoreleasing并为您释放它。

此代码:

-(id) getAutoReleasedObject
{
    __autoreleasing MyClass *obj = [MyClass new];
    return obj;
}

编译到:

-(id) getAutoReleasedObject 
{
    MyClass *obj = [MyClass new]; 
    return [obj autorelease];
}

答案 1 :(得分:3)

您必须删除对autorelease的调用:

- (MyClass *) getAutoreleasedObj {
    MyClass *obj = [[MyClass alloc] init];
    // [obj autorelease];
    return obj;
}

方法printObj现在等效于以下内容:

- (void) printObj {
    MyClass *obj = [self getAutoreleasedObj];
    // At his point there is a reference to obj
    NSLog(@"%@", obj);
    // There are no references to obj now, ARC will take care of it. 
}

我的意思是对obj的有效引用将传递给NSLog,之后,将不再提及obj

答案 2 :(得分:2)

你说:

  

如果我只是删除autorelease消息,obj将在getAutoreleasedObj结束时立即解除分配

这是不正确的。由于方法的名称(getAutoreleasedObj)不适合alloc / init / copy / mutableCopy / new模式,因此ARC会自动假定您希望obj自动释放。

您不会在getAutoreleasedObj的末尾排空任何自动释放池,因此obj将不会被释放。

代码运行时,某些自动释放池处于活动状态。如果您尚未手动设置自动释放池,则活动池是Cocoa运行循环设置的池。该池在每次通过运行循环结束时耗尽。

因此,除非您在某处设置了自己的池,否则您在getAutoreleasedObj中创建的对象将一直存在,直到运行循环的当前迭代结束。

答案 3 :(得分:0)

如上所述,

ARC中不需要autorelease。 ARC将为您解决所有问题,因此您无需担心。在“ARC概述”下:

https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

答案 4 :(得分:0)

ARC识别您的方法系列以确定何时插入版本。 以init,copy,mutableCopy,new开头的方法属于“init”系列。 ARC在调用方法中插入一个版本。在大多数情况下,您不必从方法返回自动释放的对象。 ARC智能地为您插入释放/保留。您可以通过使用NS_RETURNS_RETAINED / NS_RETURNS_NON_RETAINED

修饰方法来覆盖此行为

您需要自动释放的唯一情况是通过回写指针返回数据时。在您的情况下,您可以安全地删除自动释放呼叫。

答案 5 :(得分:0)

与ARC没有任何关系的简单答案,实际上是关于过渡过程和转换为ARC的重写器,是改变函数的最后两行:

[obj autorelease];
return obj;

return [obj autorelease];

ARC转换重写器本身不允许[x autorelease],因为它认为如果不再引用x会很危险。所以你基本上只需要确保使用[x autorelease]的返回值,在OPs情况下很容易完成。