Sam*_*hen 0 autorelease nsautoreleasepool ios automatic-ref-counting
启用ARC时,将o在此代码段中放入自动释放池吗?
- (NSObject *)obj {
NSObject *o = [[NSObject alloc] init];
return o;
}
Run Code Online (Sandbox Code Playgroud)
更重要的是,这两个代码片段之间的区别是什么?
- (NSObject *)obj {
NSObject * __autoreleasing o = [[NSObject alloc] init];
return o;
}
Run Code Online (Sandbox Code Playgroud)
与
- (NSObject *)obj {
NSObject * __strong o = [[NSObject alloc] init];
return o;
}
Run Code Online (Sandbox Code Playgroud)
启用ARC时,是否会在此代码段中放入自动释放池?
答案是,它可能,也可能不是.ARC无论如何也无法保证.在这里,方法的名称(obj)不与表示保留的返回类型的特殊名称的一个开始(例如alloc,retain,new,copy,mutableCopy),所以它返回一个非保留引用.关于"未保留的返回值"的ARC规范部分说:
在最坏的情况下,这可能涉及自动释放,但调用者不能假定该值实际上在自动释放池中.
在过去,在MRC autorelease下,在返回之前必须在这种情况下执行此操作,因为该方法需要返回非保留引用,但是某人必须拥有对该对象的强引用,否则它将被释放.由于对象是在您的方法中创建的,因此没有其他人对它进行引用,并且该方法必须在其作用域的末尾除去其强引用,因为它无法返回保留的引用,因此唯一的方法是使用autorelease pool在返回时保持强大的参考.
ARC必须与MRC保持ABI兼容(即,您应该能够用ARC替换MRC实现,反之亦然,而无需更改标头,并且呼叫者无需知道它是使用ARC还是MRC编译才能正常工作).因此,在从MRC代码调用方法的情况下,遵循与上一段相同的逻辑,您的方法必须autorelease; 根本没有办法做到这一点.
但是,ARC引入了一个聪明的可选运行时优化,可以autorelease在某些情况下消除调用者和被调用者使用ARC编译,而调用者或被调用者不需要知道另一方.这大概就是它的工作原理:在返回函数时,通常会autorelease调用ARC objc_autoreleaseReturnValue().在调用函数并保留返回值的代码中,它代之以调用objc_retainAutoreleasedReturnValue().在objc_autoreleaseReturnValue(),它查看堆栈帧上的返回地址,以查看是否将传递返回的值objc_retainAutoreleasedReturnValue().如果没有,它会autorelease.如果是,那么它将跳过autorelease,并且还修改返回地址以跳过objc_retainAutoreleasedReturnValue,从而删除a autorelease和aretain,这将取消.在objc_retainAutoreleasedReturnValue(),如果没有跳过,它就会retain.这适用于MRC到ARC呼叫,ARC到ARC呼叫和ARC到MRC呼叫,并且将消除autorelease一些ARC到ARC呼叫.
更重要的是,这两个代码片段之间的区别是什么?
第一个将它放入自动释放池,而第二个可能不会.(顺便说一句,__strong是默认值,所以第三段代码与第一段相同.)
但基本上没有充分的理由使用__autoreleasing局部变量而不是默认值(即__strong); __strong更简单,更容易思考.
通常你唯一会遇到的__autoreleasing是参数中的"指向"类型 - 如果一个函数声明它需要一个指针__autoreleasing(例如NSObject * __autoreleasing *),这意味着它将以不同的方式写入指向的变量.它需要一个指针__strong(例如NSObject * __strong *).两种方式都有效,但是呼叫者和被呼叫者需要就哪一种方式达成一致.由于NSError * __autoreleasing *在Cocoa中无处不在的使用,一个不合格的默认指向__autoreleasing(例如NSObject **手段NSObject * __autoreleasing *).
| 归档时间: |
|
| 查看次数: |
565 次 |
| 最近记录: |