繁体   English   中英

将方法返回的对象放入自动释放池吗?

[英]Will an object returned by a method be put into autorelease pool?

当ARC被启用,将o投入自动释放池在此代码段?

- (NSObject *)obj {
    NSObject *o = [[NSObject alloc] init];

    return o;
}

而且,这两个代码段之间有什么区别?

- (NSObject *)obj {
    NSObject * __autoreleasing o = [[NSObject alloc] init];

    return o;
}

- (NSObject *)obj {
    NSObject * __strong o = [[NSObject alloc] init];

    return o;
}

启用ARC后,是否将在此代码段中放入自动释放池?

答案是,可能会或可能不会。 ARC均无法保证。 在这里,方法的名称( obj )并非以表示保留的返回类型的特殊名称之一开头(例如allocretainnewcopymutableCopy ),因此它返回一个非保留的引用。 关于“未保留的返回值”ARC规范部分说:

在最坏的情况下,这可能涉及自动释放,但是调用者不得假定该值实际上在自动释放池中。

在过去,根据MRC,在这种情况下,您必须先autorelease它,然后再返回,因为要求该方法返回一个非保留的引用,但是有人必须持有对该对象的强引用,否则它将被释放。 。 由于对象是在您的方法中创建的,因此没有其他人对其进行引用,并且该方法必须在其作用域的末尾摆脱其强引用,因为它无法返回保留的引用,因此唯一的方法是拥有自动释放池在返回中具有很强的参考价值。

ARC必须保持与MRC的ABI兼容(即,您应该能够用ARC替换MRC实施,反之亦然,而无需更改标头,并且调用者不需要知道它是使用ARC还是MRC编译的即可正常工作)。 因此,在从MRC代码调用您的方法的情况下,按照与上一段相同的逻辑,您的方法必须autorelease 根本没有其他方法可以做到。

但是,ARC引入了聪明的可选运行时优化,在某些情况下,当调用方和被调用方都使用ARC编译时,它可以消除autorelease ,而调用方或被调用方无需了解另一端。 大概是这样工作的:在通常会autorelease功能的函数的返回中,ARC而是调用objc_autoreleaseReturnValue() 在调用函数并保留返回值的代码中,它改为调用objc_retainAutoreleasedReturnValue() objc_autoreleaseReturnValue() ,它在堆栈框架上查找返回地址,以查看是否将返回值传递给objc_retainAutoreleasedReturnValue() 如果没有,它将autorelease 如果是,那么它会跳过autorelease ,并修改返回地址跳过objc_retainAutoreleasedReturnValue ,从而消除两者的autoreleaseretain ,这抵消了。 objc_retainAutoreleasedReturnValue() ,如果不跳过它,它将retain 这对于MRC-to-ARC调用,ARC-to-ARC调用和ARC-to-MRC调用正确运行,并且会消除某些ARC-ARC调用的autorelease


而且,这两个代码段之间有什么区别?

第一个可能会将其放入自动释放池,而第二个可能不会。 (顺便说一下, __strong是默认值,因此第三部分代码与第一部分相同。)

但是基本上没有充分的理由对局部变量使用__autoreleasing而不是默认变量( __strong )。 __strong更容易思考。

通常,您遇到__autoreleasing的唯一时间是参数的“指针指向”类型-如果函数声明它需要指向__autoreleasing的指针(例如NSObject * __autoreleasing * ),则意味着它将写入指向指针的变量与采用指向__strong的指针的方式__strong (例如NSObject * __strong * )。 两种方法都可以,但是主叫方和被叫方需要就哪种方法达成共识。 由于可可中普遍使用NSError * __autoreleasing * ,因此不合格的默认指向__autoreleasing指针(例如, NSObject **表示NSObject * __autoreleasing * )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM