自動釋放池

葉喬木發表於2018-12-05

自動釋放池塊

自動釋放池是允許你放棄對一個物件的持有關係,但可以避免它立即被回收的一個工具,當從方法返回你的物件的時候,這個功能很有用。

  • 將建立的物件存入到自動釋放池中,不需要手動的區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 自動被釋放,兩個都被釋放 出現野指標

相關文章