gpt4 book ai didi

ios - 为什么在没有 @autoreleasepool 的 for 循环的每个循环中 NSString autorelease

转载 作者:可可西里 更新时间:2023-11-01 05:40:31 24 4
gpt4 key购买 nike

这是我的测试代码:

for (int i = 0; i < 1000000000; ++i) {
NSString *string = @"Abc";
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
}

在ARC环境中,循环不会使内存爆炸。在我的例子中,运行这个循环只需要1.2MB RAM。

但是在MRC中,除非使用@autoreleasepool代码块,否则循环会使内存爆炸。令我困惑的是有很多文章说当代码在for中时需要将代码放在@autoreleasepool中环形。但在这种情况下,没有@autoreleasepool 也没关系。请帮我解决这个问题。谢谢。

更新:如果我这样写代码:

for (int i = 0; i < 1000000000; ++i) {
NSString *string = [NSString stringWithFormat:@"aaaaaaaaaaaaaaaaaaa"];
}

这段代码会导致 ARC 和 MRC 中的内存爆炸。为什么?

stringWithFormat:

还返回一个自动释放对象。我对此感到困惑...

最佳答案

使用 ARC 编译的代码必须与未使用 ARC 编译的代码进行互操作。此外,您不能假设 Foundation,尤其是您正在调用的 NSString 的方法,是用 ARC 编译的。

那些 NSString 方法必须以这样的方式编译,以便它们可以从 ARC 和非 ARC 代码中调用。这意味着他们必须自动释放他们返回的对象,无论他们自己是否使用 ARC 编译。

但是,如果那些 NSString 方法是用 ARC 编译的,那么它们可能会使用 objc_autoreleaseReturnValue() 来执行自动释放。如果调用者也是用 ARC 编译的并且它保留了对象(因为,例如,它被分配给了一个强局部变量),那么它可能会对其使用 objc_retainAutoreleasedReturnValue()。在那种情况下,可以避免使用自动释放池。 objc_autoreleaseReturnValue() 通过检查堆栈和调用者的指令,可以检测到调用者将对返回值使用 objc_retainAutoreleasedReturnValue(),它不会自动释放该值,并且它将通过侧 channel 将这一事实传达给 objc_retainAutoreleasedReturnValue(),这样它就不会保留该值。

因此,在某些您不能依靠自己决定的特定情况下,“通常”会自动释放然后保留对象的代码不会。它只会转移所有权。

ARC 不会自动耗尽自动释放池或引入内部自动释放池。

由于不确定性,您应该始终使用 @autoreleasepool 围绕任何可能由于自动释放对象而导致内存激增的代码。例如:

for (int i = 0; i < 1000000000; ++i) @autoreleasepool {
NSString *string = @"Abc";
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
}

关于ios - 为什么在没有 @autoreleasepool 的 for 循环的每个循环中 NSString autorelease,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33642853/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com