自动释放池

自动释放池块

自动释放池是允许你放弃对一个对象的持有关系,但可以避免它立即被回收的一个工具,当从方法返回你的对象的时候,这个功能很有用。

  • 将创建的对象存入到自动释放池中,不需要手动的区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 自动被释放,两个都被释放 出现野指针

猜你喜欢

转载自blog.csdn.net/github_36850997/article/details/84839678