今天我們來看一下OC中數組對象在是如何處理對象元素的引用計數問題的,同時介紹一下自動釋放池的相關概念
一、數組對象是如何處理對象元素的引用計數問題
// // main.m // 26_NSArrayMemeryManager // // Created by jiangwei on 14-10-12. // Copyright (c) 2014年 jiangwei. All rights reserved. // #import我們定義了Dog類,然後定義了NSMutableArray數組存放兩個Dog對象,OC中在將對象放到數組中的時候,會自動調用retain方法,當數組對象本身被銷毀的時候,會調用所有元素的release方法,當移除數組中所有的元素的時候,會調用元素的release方法#import Dog.h int main(int argc, const char * argv[]) { Dog *dog1 = [[Dog alloc] init]; Dog *dog2 = [[Dog alloc] init]; NSMutableArray *array = [[NSMutableArray alloc] init]; //數組會對每一個元素retain [array addObject:dog1]; //dog1計數=2 [array addObject:dog2]; //dog2計數=2 [dog1 release]; [dog2 release]; //當數組銷毀的時候,會將所有的元素release [array release];//數組銷毀 //當數組移除所有的元素的時候,會講所有的元素release [array removeAllObjects]; return 0; }
二、自動釋放池的概念
// // main.m // 27_AutoReleasePool // // Created by jiangwei on 14-10-13. // Copyright (c) 2014年 jiangwei. All rights reserved. // #import我們在之前的文章中,定義一個對象的時候都會產生一個自動釋放池,然後在釋放池中編寫我們的代碼,自動釋放池是系統提供的一種幫助我們去管理對象的引用計數問題。但是有時候代碼必須在{...}中編寫,這樣的話就會產生作用域的問題,就是在{...}中定義的變量,在{...}外面不能使用。所以OC中就有了另外的一種方式:NSAutoreleasePool這個類#import Dog.h int main(int argc, const char * argv[]) { /* //創建一個自動釋放池 //有作用域的問題,在{}中定義的東西外部是不能訪問的,這點和NSAutoreleasePool有區別的 @autoreleasepool {//等價於[[NSAutoreleasePool alloc] init] Dog *dog2 = [[Dog alloc] init]; [dog2 retain]; }//等價於[pool release] //創建一個自動釋放池 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; Dog *dog1 = [[Dog alloc] init];//計數:1 //將dog1對象加入到自動釋放池中,卻別於之前的release方法 //加入到自動釋放池中之後,不是代表我們不需要管理引用了,只是自動釋放池自動會調用一次release //當自動釋放池銷毀的時候,釋放池會對池中每一個對象調用一次release [dog1 autorelease]; NSLog(@dog1計數:%ld,dog1.retainCount); //銷毀自動釋放池 //這時候會調用dog1的release方法,dog1對象就被銷毀了 [pool release]; */ //自動釋放池的嵌套 NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init]; //添加我們的代碼 //dog1放到了pool1中 Dog *dog1 = [[Dog alloc] init]; [dog1 autorelease]; //自動釋放池的嵌套 NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init]; //dog2放到了pool2中 Dog *dog2 = [[Dog alloc] init]; [dog2 autorelease]; //pool2銷毀了 [pool2 autorelease]; //pool1銷毀了 [pool1 release]; //下面的代碼就是有問題的 //[person setDog:[[Dog alloc] init]; //正確的寫法 //Dog *dogs = [[[Dog alloc] init] autorelease]; return 0; }
這種自動釋放池可以實現嵌套
NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];
//write code...
//pool1銷毀了
[pool1 release];
上面的代碼就相當於建立了一個自動釋放池pool1,但是在這個中間的代碼,如果要加入到這個池中,必須調用autorelease方法:
//dog1放到了pool1中 Dog *dog1 = [[Dog alloc] init]; [dog1 autorelease];而且,這樣定義一個池子還可以嵌套使用,直接看上面的例子代碼,這樣這個自動釋放池我們就可以控制了。比系統提供的自動釋放池可操作的地方很多
下面就直接對比一下:
NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];
這行代碼就相當於系統自動釋放池的 {
[pool1 release];
這行代碼就相當於系統自動釋放池的 }
這樣就好理解了吧
總結
這一篇文章主要介紹了OC中數組對象操作元素對象的時候需要處理的引用問題,以及我們可以自定義一個自動釋放池,這種方式比系統提供的自動釋放池方便,可操作性強。