Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/109.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 方法返回的对象是否会放入自动释放池?_Ios_Automatic Ref Counting_Autorelease_Nsautoreleasepool - Fatal编程技术网

Ios 方法返回的对象是否会放入自动释放池?

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放入自动释放池 片段

启用ARC时,
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代码调用方法的情况下,遵循与上面段落中相同的逻辑,方法必须
自动释放
;没有别的办法了