Ric*_*aez 8 macos memory-management objective-c clang
为什么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;
}
Run Code Online (Sandbox Code Playgroud)
2.
int main(int argc, const char * argv[])
{
NSArray *array = @[@"Hello, world!"];
NSLog(@"%@", array[0]);
}
Run Code Online (Sandbox Code Playgroud)
注意,我只关心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:..]文档中提到).
| 归档时间: |
|
| 查看次数: |
1526 次 |
| 最近记录: |