ARC如何循环工作?

时间:2018-08-14 14:45:11

标签: ios objective-c memory-management automatic-ref-counting

我搜索了很多信息,但找不到任何东西。也许我无法很好地搜索),因为我知道ARC就像编译工具一样工作。实际上,此工具代替了开发人员设置版本,并保留在汇编代码中。但是我的问题是,例如,如果我们在随机值循环中创建对象,它将如何工作?

int value = arc4random_uniform(74);
for(int i=0; i<value; ++i) {
   MyObject* my = [MyObject new];
}

所以它将如何解决,因为在编译时我们不知道对象的数量。如果它像在MyObject* my = [MyObject new];弧之后那样工作,只需添加[my release];,为什么我们要使用autoreleasepool(如果此刻将被释放)???

3 个答案:

答案 0 :(得分:3)

这取决于编译器的异想天开,它可能会根据目标体系结构,操作系统版本和/或编译器优化设置而改变。

通过循环的次数无关紧要。

有效地,这:

for(int i=0; i<value; ++i) {
   MyObject* my = [MyObject new];
}

可能编译为:

for(int i=0; i<value; ++i) {
   MyObject* my = [[MyObject new] autorelease];
}

或者这个:

for(int i=0; i<value; ++i) {
   MyObject* my = [MyObject new];
   [my release];
}

两者都是完全有效的。

通过概要分析,如果循环产生大量自动释放噪声,您可能会发现需要用for()包围@autoreleasepool {}循环的主体。也许。通常,尽管如此,大量自动释放池流量指示算法问题。优化远离内存的抖动对于性能而言通常至关重要。

答案 1 :(得分:0)

你说

  

据我所知,ARC就像编译工具一样工作。 ...所以[自动释放对象]的解决方法,因为在编译时我们不知道对象的数量。

ARC是编译时工具,但是ARC不管理自动发布对象。它们由自动释放池管理,该池在运行时进行处理。因此,在创建自动释放对象时,会将它们添加到当前池中,并且当该池耗尽时(通过让回到操作系统或通过创建自己的手动自动释放池),这些自动释放引用将被释放。

  

如果现在要释放autoreleasepool,为什么要使用它呢?

根据定义,目前自动释放的对象被释放。它们只会在游泳池排干水时释放。

随着编译器和ARC的发展,关于不创建自动发布对象,而是创建ARC将为您管理的对象的问题变得越来越复杂。您似乎以为您的代码段将生成自动释放对象,但是正如bbum所说,您没有这样的保证。它最有可能由ARC管理,而不是由自动释放池管理。

我建议您通过“工具”的“分配”工具对您的应用程序进行性能分析,并在那里查看内存使用情况。如果看到无限的内存增长,只有在循环结束时才能解决,这可能涉及自动释放对象,因此可以保证将自动释放池放入循环中。否则,不必担心,因为越来越有可能不涉及自动释放对象。

答案 2 :(得分:0)

ARC不是魔术。这很复杂,但不是魔术。

让我们看看您的示例

int value = arc4random_uniform(74);
for(int i=0; i<value; ++i) {
   MyObject* my = [MyObject new];
}

假设MyObject基于NSObject,并且没有被其他返回值覆盖,那么我们需要检查newNSObject的声明。

+ (instancetype)new OBJC_SWIFT_UNAVAILABLE("use object initializers instead");

注意:没有ARC声明。

使用默认的ARC设置,因为没有ARC声明。

所以下一个问题是“默认值是什么?”现在我们检查文档:Objective-C Automatic Reference Counting (ARC)

  

alloccopyinitmutableCopynew系列中的方法被隐式标记为__attribute__((ns_returns_retained))。可以通过显式标记方法__attribute__((ns_returns_not_retained))来抑制这种情况。

-newnew家族中,因此默认值为__attribute__((ns_returns_retained))

MyObject将返回保留+1,并且不会自动释放。

int value = arc4random_uniform(74);
for(int i=0; i<value; ++i) {
   MyObject* my = [MyObject new]/* Implied [my retain] */;
/* Implied [my release] */}