我們知道,內存分為棧,堆,塊。
棧中的內存由系統自己釋放,堆是存對象初始化的地方,塊是CPU與內存連接的緩沖器,運行速度比內存快,比CPU慢。
例如,我們NSMutableArray *array = [NSMutableArrar new];
NSMutableArray *array就在棧中,NSMutableArray類型的指針。[NSMutableArray new]開辟的內存在堆中,我們可以理解為
NSMutableArray *array --->[NSMutableArrar new];
棧中的指針指向堆中的對象。
我們用static或者const關鍵字定義常量,一般在內存塊中開辟內存空間。在塊中開辟內存空間的對象讀寫速度最快,但是我們要注意,塊的內存很小。
?
block代碼是在塊中執行的,所以它的運行速度要比delegate等效率高。但是使用block容易造成內存泄露。
原因在網上找到了:http://www.cnblogs.com/hanjun/p/3767394.html
- NSGlobalBlock:類似函數,位于text段;我們可以通過是否引用外部變量識別,未引用外部變量即為NSGlobalBlock,可以當做函數使用。
- NSStackBlock:位于棧內存,函數返回后Block將無效;
- NSMallocBlock:位于堆內存,NSMallocBlock只需要對NSStackBlock進行copy操作就可以獲取。
?
- Block_copy與copy等效,Block_release與release等效;
- 對Block不管是retain、copy、release都不會改變引用計數retainCount,retainCount始終是1;
- NSGlobalBlock:retain、copy、release操作都無效;
- NSStackBlock:retain、release操作無效,必須注意的是,NSStackBlock在函數返回后,Block內存將被回收。即使retain也沒用。容易犯的錯誤是[[mutableAarry addObject:stackBlock],(補:在arc中不用擔心此問題,因為arc中會默認將實例化的block拷貝到堆上)在函數出棧后,從mutableAarry中取到的stackBlock已經被回收,變成了野指針。正確的做法是先將stackBlock copy到堆上,然后加入數組:[mutableAarry addObject:[[stackBlock copy] autorelease]]。支持copy,copy之后生成新的NSMallocBlock類型對象。
- NSMallocBlock支持retain、release,雖然retainCount始終是1,但內存管理器中仍然會增加、減少計數。copy之后不會生成新的對象,只是增加了一次引用,類似retain;
- 盡量不要對Block使用retain操作。