转换到ARC时,我收到以下编译错误:"删除未使用的自动释放消息"是不安全的。
如果我只是删除autorelease消息,obj将在getAutoreleasedObj结束时立即释放,这将导致printObj崩溃。那么如何处理自动释放的对象,并将以下代码转换为ARC?
- (MyClass *) getAutoreleasedObj {
MyClass *obj = [[MyClass alloc] init];
[obj autorelease];
return obj;
}
- (void) printObj {
NSLog(@"%@", [self getAutoreleasedObj];
}
答案 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概述”下:
答案 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情况下很容易完成。