內存管理思想

一、內存管理的思考方式

內存管理的思想包括以下四點:

1、自己生成的對象,自己所持有

2、非自己生成的對象,自己也能持有

3、不再需要自己持有的對象時,要釋放

4、非自己持有的對象 不能釋放

自己生成的對象自己持有

?alloc 、new、copy、mutableCopy

這些名稱開頭的方法名意味著自己生成的對象只有自己持有;上文中出現了一系列的自己這個詞,可以將自己理解為“對象的使用環境”,也可以理解為編程人員“自身”。下面寫出了自己生成并持有對象的源代碼。我們在這里使用alloc方法:

//自己生成對象并持有對象

id obj =[ [NSObject alloc] init];

//自己持有對象

使用alloc類方法就能自己生成并持有對象。指向生成并持有對象的指針被賦給變量obj,另外,使用new類方法也可以生成并持有對象。和alloc時完全一致的

//自己生成對象并持有對象

id obj =[NSObject new];

//自己持有對象

copy方法利用基于NSCopying方法約定,由各類實現的copyWithZone:方法生成并持有對象副本。與copy方法類似,mutableCopy方法利用基于NSMutableCopying方法約定,由各類實現的mutableCopyWithZone:方法生成并持有對象的副本。 用這些方法生成的對象,雖然是對象的副本,但是和alloc、new一樣,在”自己生成并持有對象“這點上沒有發生改變;

非自己生成的對象,自己也能持有

用alloc/new/copy/mutableCopy以外的方法取得的對象,因為非自己生成并持有,所以自己不是該對象的持有者。看以下源代碼:

//取得非自己生成并持有的對象

id obj = [NSMutableArray array];

//取得對象的存在,但自己不持有對象

上述代碼中,NSmutableArray類對象被賦值給變量obj,但變量obj自己并不持有該對象。使用retain方法可以持有對象

//取得非自己生成并持有的對象

id obj = [NSMutableArray array];

//取得對象的存在,但自己不持有對象

[obj retain];

//自己持有對象

通過retain方法,非自己生成的對象跟用alloc/new/copy/mutableCopy方法生成并持有的對象一樣,成為了自己所持有的。

不再需要自己持有的對象時 ,要釋放

自己持有的對象,一旦不在需要,持有者有義務釋放該對象。釋放使用release方法。

//自己生成并持有對象

id obj = [[NSObject alloc] init];

//自己持有對象

[obj release];

//釋放對象,指向 對象的指針? 仍然被保留在變量obj中,貌似可以訪問。但是 對象 一經釋放不可訪問

如此,用alloc方法由自己生成并持有的對象就通過release方法釋放了。自己生成而非自己所持有的對象,若用retain方法變為自己持有,也同樣可以用release方法釋放。

//取得非自己生成并持有的對象

id obj = [NSMutableArray array];

//取得對象存在,但自己不持有對象

[obj retain];

//自己持有對象

[obj release];

//釋放對象,對象? 不可再被訪問

那么如果要用某個方法生成對象,并將其返還給該方法的調用方,那么它應該怎么操作呢,如下:

- ( id ) allocObject

{

??????? //自己生成并持有對象

?????? id obj = [[NSObject alloc ] init ];

??????? //自己持有對象

????? return obj;

}

如上,原封不動返回用alloc方法生成并持有的對象,就能讓調用方也持有該對象。

//取得非自己生成并持有的對象

id obj1 = [obj0 allocObject];

//自己持有對象

那么,如何像調用[NSMutableArray array] 方法使取得的對象存在,但自己不持有對象,又是如何實現的呢?如下:

- ( id ) allocObject

{

??????? //自己生成并持有對象

???? ?? id obj = [[NSObject alloc ] init ];

?????? [obj autorelease];

?????? //取得對象的存在,但是自己不持有對象。

??????? return obj;

}

上述代碼中,我使用了autorelease方法。用該方法,可以使取得的對象存在,但自己不持有對象。以后有時間我會詳細介紹autorelease。

id obj1 = [obj0 object];

//取得的對象存在,但自己不持有對象。

當然也可以像前文中的NSMutableArray一樣,通過retain 方法,將調用autorelease方法取得的對象變為自己持有。

無法釋放非自己持有的對象

對于由alloc/new/copy/mutableCopy 方法生成并持有的對象,或是retain方法持有的對象,由于持有者是自己,所以在不需要該對象的時候,需要將其釋放。而由此以外所得到的對象絕對不能釋放。如果在應用程序中釋放了非自己所持有的對象就會造成崩潰。例如自己生成的并持有對象后,在釋放完不再需要的對象之后再次釋放。

//自己生成并持有對象

id obj = [[NSObject alloc] init];

//自己持有對象

[objc release];

//對象已被釋放

[obj release];

//釋放之后再次釋放已非自己持有的對象,應用程序崩潰

//崩潰情況:再度廢棄一經廢棄了的對象時崩潰?? 、 訪問一經廢棄的對象時崩潰;

或者在“取得的對象存在,但自己不持有對象”時釋放

id obj1 = [obj0 object];

[obj1 release];

//釋放了非自己持有的對象,這肯定會導致應用程序崩潰

如這些例子所示,釋放非自己持有的對象會造成程序崩潰。因此絕對不要去釋放非自己持有的對象。

最后編輯于

推薦閱讀更多精彩內容