自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

深度解析Objective-C內(nèi)存管理教程

移動(dòng)開發(fā) iOS
本文介紹的是深度解析Objective-C內(nèi)存管理教程,介紹了Objective-C中的內(nèi)存問題,來看詳細(xì)內(nèi)容。

深度解析Objective-C內(nèi)存管理教程是本文要介紹的內(nèi)容,不多說,來看內(nèi)容。iPhone系統(tǒng)中的Objective-C的內(nèi)存管理機(jī)制是比較靈活的,即可以拿來像C/C++一樣用,也可以加個(gè)AutoreleasePool讓它升級(jí)為半自動(dòng)化的內(nèi)存管理語(yǔ)言。當(dāng)然,也不能拿JAVA虛擬機(jī)中的全自動(dòng)化GC來比

引用計(jì)數(shù)是實(shí)例對(duì)象的內(nèi)存回收唯一參考

引用計(jì)數(shù)(retainCount)是Objective- C管理對(duì)象引用的唯一依據(jù)。調(diào)用實(shí)例的release方法后,此屬性減一,減到為零時(shí)對(duì)象的dealloc方法被自動(dòng)調(diào)用,進(jìn)行內(nèi)存回收操作,也就是說我們永不該手動(dòng)調(diào)用對(duì)象的dealloc方法。

主要操作接口:

1、alloc, allocWithZone,new(帶初始化)

   為對(duì)象分配內(nèi)存,retainCount為“1”,并返回此實(shí)例

2、retain

  1. retainCount 加“1” 

3、release

   retainCount 減“1”,減到“0”時(shí)調(diào)用此對(duì)象的dealloc方法
  
4、copy,mutableCopy

   復(fù)制一個(gè)實(shí)例,retainCount數(shù)為“1”,返回此實(shí)例。所得到的對(duì)象是與其它上下文無關(guān)的,獨(dú)立的對(duì)象(干凈對(duì)象)。

5、autorelease

在當(dāng)前上下文的AutoreleasePool棧頂?shù)腶utoreleasePool實(shí)例添加此對(duì)象,由于它的引入使Objective-C(非GC管理環(huán)境)由全手動(dòng)內(nèi)存管理上升到半自動(dòng)化。

  1. - (void)setMyArray:(NSMutableArray *)newArray {     
  2.     if (myArray != newArray) {     
  3.         [myArray release];     
  4.         myArray = [newArray retain];     
  5.     }     
  6. }    

假設(shè)這個(gè)類的一個(gè)實(shí)例為'a',調(diào)用setMyArray后,我們就可以說a擁有了一個(gè)新的myArray 實(shí)例,也可以說a引用了一個(gè)新的myArray實(shí)例。其中調(diào)用的retain方法,使myArray的retainCount加一,我們需要注意以下兩個(gè)地方:
 
1,setMyarray方法中,在retain之前先release了舊實(shí)例一次

2,在本實(shí)例的dealloc方法中,本應(yīng)該是要再次release當(dāng)前實(shí)例的,但回頭看看參考內(nèi)存管理準(zhǔn)則。它并不合理,對(duì)吧。。。多了一次 release。這里比較推薦的做法是:

  1. [myArray setMyArray:nil]; 

這樣可以巧妙的使當(dāng)前實(shí)例release而不出錯(cuò)(我們可以向nil發(fā)送消息~其實(shí)它本身就是個(gè)整數(shù)0),并符合我們的內(nèi)存管理準(zhǔn)則。更主要的是,很簡(jiǎn)單,你不需要考慮過多的事情。

數(shù)組(Array)是一個(gè)比較特別的例子,當(dāng)你往數(shù)組里面添加一個(gè)對(duì)象時(shí)。數(shù)組里面存儲(chǔ)的并不是這個(gè)對(duì)象的拷貝,而只是一個(gè)指向該對(duì)象的指針。數(shù)組在保存這個(gè)指針的同時(shí)會(huì)向指針?biāo)傅膶?duì)象發(fā)送一個(gè)retain消息,相應(yīng)的,對(duì)象的持有計(jì)數(shù)會(huì)增加。將對(duì)象從數(shù)組中移除的時(shí)候,同樣會(huì)向?qū)ο蟀l(fā)送release消息,對(duì)象的持有計(jì)數(shù)會(huì)減小。當(dāng)我們釋放這個(gè)數(shù)組時(shí),會(huì)向保存在這個(gè)數(shù)組中的所有對(duì)象發(fā)送release消息。看下面的兩個(gè)例子:

1、沒有釋放內(nèi)存的版本

  1. array = [[NSMutableArray alloc] init];  
  2. for ( i = 0; i < 10; i++) {  
  3. newNumber = [[NSNumber alloc]initWithInt:(i * 3)];  
  4. [array addObject:newNumber];  

上面的代碼在創(chuàng)建newNumber對(duì)象時(shí),向?qū)ο蟮陌l(fā)送了retain消息,對(duì)象的持有計(jì)數(shù)變?yōu)?。當(dāng)向array中添加這個(gè)對(duì)象的引用時(shí),又向?qū)ο蟀l(fā)送了一次retain消息,這樣對(duì)象的持有計(jì)數(shù)就變?yōu)?了,在使用完array時(shí),我們會(huì)習(xí)慣性的釋放掉array,但這樣并不會(huì)釋放array所持有的對(duì)象,而只是使所有對(duì)象的持有計(jì)數(shù)變?yōu)?,這些對(duì)象依然會(huì)占用著內(nèi)存。

2、釋放內(nèi)存的版本

  1. for (i = 0; i < 10; i++) {  
  2. newNumber = [[NSNumber alloc]initWithInt:(i*3)];  
  3. [array addObject:newNumber];  
  4. [newNumber release];  

AutoreleasePool使 Objective-C成為內(nèi)存管理半自動(dòng)化語(yǔ)言。

如果僅僅是上面這些,很簡(jiǎn)單,對(duì)吧。但往往很多人都會(huì)迷糊在自動(dòng)內(nèi)存管理這塊上,感覺像是有魔法,但其實(shí)原理也很簡(jiǎn)單~

先看看最經(jīng)典的程序入口程序:

  1. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
  2. int retVal = UIApplicationMain(argc, argv, nil, nil);  
  3. [pool release]; 

我們先把pool看成一個(gè)普通對(duì)象~很簡(jiǎn)單,先是alloc,pool的retainCount為1。第三句release,retainCount為0,自動(dòng)調(diào)用它的dealloc方法。它和任何其它普通對(duì)象沒任何區(qū)別。

魔法在哪里?

在聲明pool后,release它之前的這段代碼,所有段里的代碼(先假設(shè)中間沒有聲明其它的AutoreleasePool實(shí)例),凡是調(diào)用了 autorelase方法的實(shí)例,都會(huì)把它的retainCount加1,并在此pool實(shí)例中添1次此實(shí)例要回收的記錄以做備案。當(dāng)此pool實(shí)例 dealloc時(shí),首先會(huì)檢查之前備案的所有實(shí)例,所有記錄在案的實(shí)例都會(huì)依次調(diào)用它的release方法。

代碼:

  1. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];     
  2. NSObject *o = [[NSObject alloc] init];     
  3. [o autorelease];                                //在pool實(shí)例dealloc時(shí),release一次此實(shí)例,重要的是并不是在此行去release     
  4. NSLog(@"o retainCount:%d",[o retainCount]);    //此時(shí)還可以看到我們的o實(shí)例還是可用的,并且retainCount為1     
  5. [pool release];    //pool 的 retainCount 為0,自動(dòng)調(diào)用其dealloc方法,我們之前備案的小o也將在這里release一次(因?yàn)樵蹅冎皟H僅autorelease一次)  

 

真對(duì)同一個(gè)實(shí)例,同一個(gè)Pool是可以多次注冊(cè)備案(autorelease)的。在一些很少的情況化可能會(huì)出現(xiàn)這種需求:

代碼:

  1. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];     
  2. NSObject *o = [[NSObject alloc] init];     
  3. [o retain];     
  4. [o autorelease];     
  5. [o autorelease];     
  6. [pool release];    

我們調(diào)用了兩次A類(retainCount加1的方法),使其retainCount為2,而接下來的兩次autorelease方法調(diào)用,使其在pool中注冊(cè)備案了兩次。這里的pool將會(huì)在回收時(shí)調(diào)用此實(shí)例的兩次release方法。使其 retainCount降為0,完成回收內(nèi)存的操作,其實(shí)這也是完全按照內(nèi)存管理規(guī)則辦事的好處~

AutoreleasePool 是被嵌套的!

池是被嵌套的,嵌套的結(jié)果是個(gè)棧,同一線程只有當(dāng)前棧頂pool實(shí)例是可用的:

  1. |  pool_3  |  
  2. |  ---------      |  
  3. |  pool_2      |  
  4. |  ---------   |  
  5. |  pool_1  |  
  6. |_______| 

其代碼如下:

  1. NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];     
  2. NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init];     
  3. NSAutoreleasePool *pool3 = [[NSAutoreleasePool alloc] init];     
  4. NSObject *o = [[NSObject alloc] init] autorelease];     
  5. [pool3 release];     
  6. [pool2 release];     
  7. [pool1 release];    

我們可以看到其棧頂是pool3,o的autorelease是把當(dāng)前的release放在棧頂?shù)膒ool 實(shí)例管理。。。也就是pool3。
在生命周期短,產(chǎn)生大量放在autoreleasePool中管理實(shí)例的情況下經(jīng)常用此方法減少內(nèi)存使用,達(dá)到內(nèi)存及時(shí)回收的目的。

AutoreleasePool還被用在哪里?

在上面的例子里,也可以看到,我們?cè)趫?zhí)行autorelease方法時(shí),并沒有時(shí)時(shí)的進(jìn)行 release操作~它的release被延時(shí)到pool實(shí)例的dealloc方法里。這個(gè)小細(xì)節(jié)使我們的Objective-C用起來可以在方法棧中申請(qǐng)堆中的內(nèi)存,創(chuàng)建實(shí)例,并把它放在當(dāng)前pool中延遲到此方法的調(diào)用者釋放.

小結(jié):深度解析Objective-C內(nèi)存管理教程的內(nèi)容介紹完了,希望本文對(duì)你有所幫助!

責(zé)任編輯:zhaolei 來源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-07-19 15:15:09

Objective-C 內(nèi)存

2011-05-11 15:45:50

內(nèi)存管理Objective-C

2011-08-11 17:39:25

Objective-C筆試題

2011-07-21 09:42:27

Objective-C 內(nèi)存 Autoreleas

2013-04-11 14:37:36

Objective-CiOS內(nèi)存管理系統(tǒng)自動(dòng)創(chuàng)建新的aut

2011-07-21 10:10:42

Objective-C 內(nèi)存 Autoreleas

2011-07-21 09:32:07

Objective-C 內(nèi)存 Autoreleas

2011-08-15 14:02:36

Objective-C

2011-07-20 17:04:43

Objective-C 內(nèi)存 內(nèi)存泄露

2013-04-11 14:32:00

Objective-CiOS開發(fā)內(nèi)存管理@synthesize

2011-07-18 17:14:16

Objective-C 內(nèi)存 Cocoa

2011-08-10 18:07:29

Objective-C反射

2011-08-01 11:37:41

iPhone Objective- 內(nèi)存

2011-08-16 17:43:47

Objective-C內(nèi)存管理Autorelease

2013-03-27 12:54:00

iOS開發(fā)Objective-C

2011-08-18 13:28:35

Objective-C內(nèi)存

2011-07-08 13:49:46

Objective-C UUID

2013-04-11 14:16:57

Objective-CiOS開發(fā)內(nèi)存管理

2011-08-05 15:46:32

Objective-C 程序設(shè)計(jì)

2013-04-11 13:57:27

Objective-CiOS開發(fā)內(nèi)存管理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)