自动释放池块
自动释放池是允许你放弃对一个对象的持有关系,但可以避免它立即被回收的一个工具,当从方法返回你的对象的时候,这个功能很有用。
- 将创建的对象存入到自动释放池中,不需要手动的区release 对象了
- 在池子销毁的时候,就会自动调用池子中所有的release
1 程序的入口处于在main 函数
这就意味着整个应用都在自动释放池中,所有的对象最后都会被回收。
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
2 autoreleasepool 使用的场景
Cocoa 框架希望代码能在 自动释放池中执行,否则对象将无法被释放,导致应用发生内存泄露。
AppKit 和 UIKit 框架 循环的迭代放入自动释放池中,我们不需要创建自动释放池。
- 场景1 当有一个创建了很多临时对象的循环时,使用自动释放池释放掉临时内存
for (int i = 0; i < 10000; i ++) {
// 使用自动释放池释放掉临时内存
@autoreleasepool{
Person *p = [[Person alloc]init];
p.name = @"1213";
p.age = i;
}
}
- 场景2 当你自己创建一个线程开启任务的时候,每一个线程都有自己的autorelease 块栈,主线程的自动释放池默认开启,自定义的线程必须手动开启。
NSThread *thred = [[NSThread alloc]initWithTarget:self selector:@selector(countStart) object:nil];
[thred start];
- (void)countStart
{
// 新的线程的代码
@autoreleasepool{
for (int i = 0; i < 10000; i ++) {
// 使用自动释放池释放掉临时内存
@autoreleasepool{
Person *p = [[Person alloc]init];
p.name = @"1213";
p.age = i;
}
}
}
}
自动释放池使用注意点
- 自动释放池可以进行嵌套使用
- 如果把一个对象重复加载到自动释放池中,就会出现野指针。
// 创建1个对象
Person *p1 = [[Person alloc]init];
p1.name = @"Alexander";
//
@autoreleasepool
{
// p1 加载进入自动释放池
[p1 autorelease];
@autoreleasepool
{
// 重复加载进来 仍然是第一个
[p1 autorelease];
}
}// 代码执行到此处 p1 自动被释放,两个都被释放 出现野指针