在main()中省略@autoreleasepool {}的后果是什么? [英] What are the consequences of omitting @autoreleasepool { } in main()?

查看:123
本文介绍了在main()中省略@autoreleasepool {}的后果是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么Objective-C命令行和 iOS 程序的Xcode 4.x模板添加 @autoreleasepool {} 零件包装 main()的代码?请注意,这不会发生在 OS X 应用程序模板。



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



最后,由于所有内存在任何程序退出时释放,为什么 >重要性?






或者换句话说,忽略 @autoreleasepool在命令行 iOS 中的 main() Objective-C程序?



这两段代码编译并似乎工作等同:



/ p>

  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 在堆栈上没有自动释放池时不起作用。



c(你在你的例子中),所以你可以省略它在理论上,然而大多数Apple框架确实使用自动释放对象。



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



编辑:



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



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



我想OS X不添加autorelease池到模板,因为程序员也可以使用垃圾收集器



刚刚创建了一个OS X项目,并且 @autoreleasepool 就是这样。事实上,没有它的唯一模板是一个核心基金会项目,它不是真正的Obj-C,它是纯C。



编辑3:和一些googling)



随着ARC的引入,自动释放池被重写。当它们是框架特征之前,现在它们是一个语言(Obj-C)特征。它们的实现方式不同。看来,每个新的线程都有一个隐式自动释放池。使用 @autoreleasepool 实际上不会在一些线程堆栈上创建新的自动释放池,它只是在隐式自动释放池(这样你就可以消耗一切自动释放后标记)。这意味着没有办法创建一个示例,当 @autoreleasepool 省略时触发警告或错误。



这被认为是一个实现细节,所以它可以很容易地在将来改变(或当使用另一个编译器!)。这就是为什么对于每个新线程仍然建立一个 @autoreleasepool (例如 - [NSThread detachWithSelector:..] 文档)。


Why do the Xcode 4.x templates for Objective-C command-line and iOS programs add the @autoreleasepool {} part wrapping main()'s code? Note that this doesn't happen for the OS X application template.

Why don't OS X applications do the same? Why don't both use the same method?

Finally, since all memory is released when any program exits, why is all of this of practical importance?


Or to ask it differently, what are the practical consequences of omitting @autoreleasepool { ... } in main() for a command line or an iOS Objective-C program?

These two pieces of code compile and seem to work equivalently:

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]);
}


Note, I only care about the explanation in the ARC context. ARC forbids the explicit use of autorelease.

解决方案

autorelease doesn't work if there is no autorelease pool on the stack.

It's not really necessary to use autoreleased objects in objective-c (as you do in your examples), so you can omit it in theory, however most Apple frameworks do use autoreleased objects heavily.

Normally, every thread should have at least one autorelease pool, otherwise using any Obj-C code is very unsafe. Setting up an autorelease pool at the beginning of main is then a very good practice.

EDIT:

In ARC, although explicit autorelease is forbidden, autorelease calls are still there (added by the compiler). That implies the need for an autorelease pool.

This has nothing to do with releasing the memory. The very existence of an autorelease pool is necessary. Even if it isn't ever drained.

I guess that OS X doesn't add the autorelease pool to the template because the programmers can also use a garbage collector (although it is deprecated now).

EDIT 2:

Just created an OS X project and the @autoreleasepool is there. In fact, the only template without it is a "Core Foundation" project which is not really Obj-C, it's pure C.

EDIT 3: (After some more thinking and some googling)

With the introduction of ARC, autorelease pools were rewritten. When before they were a framework feature, now they are a language (Obj-C) feature. They are implemented differently. It seems that every new thread has an implicit autorelease pool now. Using @autoreleasepool doesn't actually create a new autorelease pool on some thread stack any more, it just puts a mark to the implicit autorelease pool (so that you can drain everything autoreleased after the mark). That means there is no way to create an example triggerring warnings or errors when @autoreleasepool is omitted.

However, this is considered to be an implementation detail, so it can be easily changed in future (or when another compiler is used!). That's why it's good practice to still set up an @autoreleasepool for every new thread (mentioned, for example, in -[NSThread detachWithSelector:..] documentation).

这篇关于在main()中省略@autoreleasepool {}的后果是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆