Objective-C中release和nil的關係

來源:互聯網
上載者:User

標籤:

 (iphone/ipad)淺談Objective-C中release和nil的關係分類: iPhone/iPad開發技術2011-12-09 01:40 2515人閱讀 評論(4) 收藏 舉報uiviewcrashnull終端

注意到經常有一個這樣的問題:某指標對象先release後=nil,這裡後跟個=nil有什麼作用?不寫行不行?

簡單一點說是,release是用來釋放記憶體,nil是將對象指標設為null,nil本身對記憶體沒什麼影響,但他處理指標,尤其是避免野指標倒是很有必要。

舉一個例子:

NSString *str=[[NSString alloc] init];

當我不需要str時

執行[str release];

str 的retain值減1,但是如果當前retain值>0,卻緊隨其後加一句str=nil;那麼這時[str retainCount]應該為0,因為[nil retainCount]==0;但這時很明顯存在記憶體泄露。

所以一個很好的寫作習慣是:

當對象的retainCount==1時,寫完[str release];後接著寫上str=nil;       這樣,當在後面的代碼再次調用str相關的方法屬性,也不會報錯,因為之前已經將str設定為空白指標,再調用str的方法也會被認為是null,不會真正調用,更不會報錯。

例如下列代碼:(以下所有程式碼片段都已經過實際操作驗證)

 

[cpp] view plaincopy
  1. UIView *view1=[[UIView alloc] init];  
  2.     UIView *view2=[view1 retain];  
  3.     int i=[view1 retainCount];  
  4.     NSLog(@"i:%d",i);  
  5.     [view1 release];  
  6.     view1=nil;  
  7.     [view1 addSubview:view2];  

整個程式運行,是不會crash的。但是存在記憶體泄露。

 

 

但是,現在又有另外一個問題,請看下列代碼:

 

[cpp] view plaincopy
  1. UIView *view1=[[UIView alloc] init];  
  2.     UIView *view2=[view1 retain];  
  3.     int i=[view1 retainCount];  
  4.     NSLog(@"i:%d",i);  
  5.     [view1 release];  
  6.     view1=nil;  
  7.     [view1 addSubview:view2];  
  8.     i=[view1 retainCount];  
  9.     NSLog(@"i:%d",i);  
  10.     i=[view2 retainCount];  
  11.     NSLog(@"i:%d",i);  
  12.     [view2 release];  
  13.     i=[view2 retainCount];  
  14.     NSLog(@"i:%d",i);  

請問終端輸出的log應該是什嗎?

 

第一個i=2,沒問題,因為view1 init了一次,retain了1次,retain值為2。

第二個i=0,根據上面所講的推斷,也沒問題,因為之前view1=nil,null 指標的retainCount值為0。

第三個i=1,也沒什麼問題,因為view2是一個被賦了值的新指標,它不同於指標view1,二者是2個獨立的指標,而且,view2還被賦了值分配了記憶體位址。

但是,第四個i呢?i=?

答案是i=1。為什麼會這樣?下面是真實輸出結果:

 

[cpp] view plaincopy
  1. 2011-12-09 01:17:07.364 ReleaseNildemo[19115:f803] i:2  
  2. 2011-12-09 01:17:07.365 ReleaseNildemo[19115:f803] i:0  
  3. 2011-12-09 01:17:07.366 ReleaseNildemo[19115:f803] i:1  
  4. 2011-12-09 01:17:07.367 ReleaseNildemo[19115:f803] i:1  

為什麼會這樣?按推理說,程式執行到輸出這句應該crash才對,我運行了好幾遍,確實沒有出現。晚上在網上和其他程式員討論這個問題,有人啟動並執行情況是“有時候會crash,有時候不會。斷點的話不會crash”,最後大家討論的話題開始變成“系統是先輸出還是先回收?”,更有甚者,有人輸出了一下記憶體位址,發現是view2 release前後輸出的是同一個記憶體位址,說明,這個東西記憶體雖然釋放了,但是系統還沒來得及回收。

 

有時候crash,原因是你向一塊未申請的記憶體發送了一條訊息,最終成了系統回收速度問題了,所以,個人認為,以後碰到類似這種問題,乾脆手動init,release,至少這樣能很快釋放,更便於清楚當前對象的記憶體情況。

 

以上是我對release nil操作的一些理解,歡迎更多人加入討論

Objective-C中release和nil的關係

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.