Ios 方法返回的对象是否会放入自动释放池?
启用ARC时,Ios 方法返回的对象是否会放入自动释放池?,ios,automatic-ref-counting,autorelease,nsautoreleasepool,Ios,Automatic Ref Counting,Autorelease,Nsautoreleasepool,启用ARC时,o是否会放入此代码段中的自动释放池 - (NSObject *)obj { NSObject *o = [[NSObject alloc] init]; return o; } 更重要的是,这两段代码之间有什么区别 - (NSObject *)obj { NSObject * __autoreleasing o = [[NSObject alloc] init]; return o; } vs 启用ARC时,此代码中将o放入自动释放池 片段
o
是否会放入此代码段中的自动释放池
- (NSObject *)obj {
NSObject *o = [[NSObject alloc] init];
return o;
}
更重要的是,这两段代码之间有什么区别
- (NSObject *)obj {
NSObject * __autoreleasing o = [[NSObject alloc] init];
return o;
}
vs
启用ARC时,此代码中将o放入自动释放池
片段
答案是,可能会,也可能不会。无论哪种方式,ARC都不能保证。这里,方法名称(obj
)不是以指示保留返回类型的特殊名称之一开头(例如alloc
,retain
,new
,copy
,mutableCopy
),因此它返回非保留引用。报告说:
在最坏的情况下,这可能涉及自动释放,但呼叫者必须
不假定该值实际上在自动释放池中
在过去,在MRC下,在这种情况下,您必须在返回之前执行自动释放
操作,因为该方法需要返回非保留引用,但必须有人持有对该对象的强引用,否则它将被释放。由于该对象是在您的方法中创建的,因此没有其他人有对它的引用,并且该方法必须在其作用域的末尾除去其强引用,因为它无法返回保留的引用,因此唯一的方法是让自动释放池在整个返回过程中保留强引用
ARC必须与MRC保持ABI兼容(即,您应该能够用ARC替换MRC实现,反之亦然,而无需更改头,调用方不需要知道它是用ARC还是MRC编译的,才能正常工作)。因此,在从MRC代码调用方法的情况下,遵循与上面段落中相同的逻辑,方法必须自动释放
;没有其他方法可以做到这一点
但是,ARC引入了一个聪明的可选运行时优化,在某些情况下,当调用方和被调用方都使用ARC编译时,调用方或被调用方不需要知道另一方,可以消除自动释放
。这大致就是它的工作原理:在返回函数时,通常会调用autorelease
,而ARC会调用objc\u autoreleaseReturnValue()
。在调用函数并保留返回值的代码中,它会调用objc\u retainAutoreleasedReturnValue()
。在objc\u autoreleaseReturnValue()
中,它查看堆栈帧上的返回地址,以查看返回值是否将传递给objc\u retainaustorereleasereturnvalue()
。如果没有,它将自动释放。如果是,则它将跳过自动释放
,还将修改返回地址以跳过objc\u retainAutoreleasedReturnValue
,从而同时删除自动释放
和保留
,从而取消。在objc_retainAutoreleasedReturnValue()
中,如果不跳过它,它将只保留
。这适用于MRC到ARC调用、ARC到ARC调用和ARC到MRC调用,并将消除某些ARC到ARC调用的autorelease
更重要的是,这两段代码之间有什么区别
- (NSObject *)obj {
NSObject * __autoreleasing o = [[NSObject alloc] init];
return o;
}
第一个将把它放入自动释放池,而第二个可能不会。(顺便说一下,\uu strong
是默认值,因此第三段代码与第一段代码相同。)
但是,对于局部变量使用\uuu autoreleasing
而不是默认值(即\uu strong
)基本上没有充分的理由<代码>\uu strong更简单,更容易思考
通常,您唯一会遇到的\uu自动删除
是在参数中的“指针指向”类型中——如果函数声明它接受指向\uu自动删除
(例如NSObject*\uu自动删除*
)的指针,这意味着它将以不同的方式写入指向的变量,而不是将指针指向\uu strong
(例如NSObject*\uu strong*
)。这两种方法都可以,但是呼叫者和被呼叫者需要就哪种方法达成一致。由于Cocoa中普遍使用NSError*\uuuu autoreleasing*
,非限定的默认值为指向\uu autoreleasing
(例如NSObject**
表示NSObject*\uu autoreleasing*
)
启用ARC时,此代码中将o放入自动释放池
片段
答案是,可能会,也可能不会。无论哪种方式,ARC都不能保证。这里,方法名称(obj
)不是以指示保留返回类型的特殊名称之一开头(例如alloc
,retain
,new
,copy
,mutableCopy
),因此它返回非保留引用。报告说:
在最坏的情况下,这可能涉及自动释放,但呼叫者必须
不假定该值实际上在自动释放池中
在过去,在MRC下,在这种情况下,您必须在返回之前执行自动释放
操作,因为该方法需要返回非保留引用,但必须有人持有对该对象的强引用,否则它将被释放。由于该对象是在您的方法中创建的,因此没有其他人有对它的引用,并且该方法必须在其作用域的末尾除去其强引用,因为它无法返回保留的引用,因此唯一的方法是让自动释放池在整个返回过程中保留强引用
ARC必须与MRC保持ABI兼容(即,您应该能够用ARC替换MRC实现,反之亦然,而无需更改头,调用方不需要知道它是用ARC还是MRC编译的,才能正常工作)。因此,在从MRC代码调用方法的情况下,遵循与上面段落中相同的逻辑,方法必须自动释放
;没有别的办法了