gpt4 book ai didi

objective-c - 在 main() 中省略 @autoreleasepool { } 会产生什么后果?

转载 作者:太空狗 更新时间:2023-10-30 03:31:59 26 4
gpt4 key购买 nike

为什么 Objective-C 命令行iOS 程序的 Xcode 4.x 模板添加了 @autoreleasepool {}部分包装 main()的密码?请注意,OS X 应用程序模板不会发生这种情况。

为什么 OS X 应用程序不这样做?为什么两者不使用相同的方法?

最后,由于所有内存在任何程序退出时都会被释放,为什么所有这些都具有实际的重要性?


或者换种说法,省略 @autoreleasepool { ... } 的实际后果是什么?在 main()用于命令行iOS Objective-C 程序?

这两段代码编译后似乎等效地工作:

1.

int main(int argc, const char * argv[])
{
@autoreleasepool {
NSArray *array = @[@"Hello, world!"];
NSLog(@"%@", array[0]);
}
return 0;
}

2.

int main(int argc, const char * argv[])
{
NSArray *array = @[@"Hello, world!"];
NSLog(@"%@", array[0]);
}

注意,我只关心ARC上下文中的解释。 ARC 禁止显式使用 autorelease .

最佳答案

如果堆栈上没有自动释放池,

autorelease 将不起作用。

在 objective-c 中使用自动释放对象并不是真正必要的(就像您在示例中所做的那样),因此理论上您可以省略它,但是大多数 Apple 框架确实大量使用自动释放对象。

通常情况下,每个线程都应该至少有一个自动释放池,否则使用任何 Obj-C 代码都是非常不安全的。在 main 的开头设置一个自动释放池是一个很好的做法。

编辑:

在 ARC 中,虽然显式 autorelease 被禁止,但 autorelease 调用仍然存在(由编译器添加)。这意味着需要一个自动释放池。

这与释放内存无关。自动释放池的存在是必要的。即使它从未耗尽。

我猜想 OS X 不会将自动释放池添加到模板中,因为程序员还可以使用垃圾收集器(尽管现在已弃用)。

编辑 2:

刚刚创建了一个 OS X 项目,@autoreleasepool 就在那里。事实上,唯一没有它的模板是一个“核心基础”项目,它不是真正的 Obj-C,它是纯 C。

编辑 3:(经过更多思考和谷歌搜索)

随着 ARC 的引入,自动释放池被重写。以前它们是框架功能,现在它们是语言 (Obj-C) 功能。它们的实现方式不同。现在似乎每个新线程都有一个隐式 自动释放池。使用 @autoreleasepool 实际上不再在某个线程堆栈上创建新的自动释放池,它只是为隐式自动释放池添加一个标记(以便您可以清空标记后自动释放的所有内容)。这意味着当 @autoreleasepool 被省略时,无法创建触发警告或错误的示例。

然而,这被认为是一个实现细节,所以它可以在未来很容易地改变(或者当使用另一个编译器时!)。这就是为什么仍然为每个新线程设置一个 @autoreleasepool 是好的做法(例如,在 -[NSThread detachWithSelector:..] 文档中提到)。

关于objective-c - 在 main() 中省略 @autoreleasepool { } 会产生什么后果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18422190/

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