Objective-C 2.0 with Cocoa Foundation— 9,記憶體管理

來源:互聯網
上載者:User

9.1前言

   記憶體管理在objective-C 2.0中是非常重要的,記憶體管理做得好不好,最直觀的就是反應在你的程式crash上面。想要你的程式健壯穩定,那麼請務必搞明白記憶體管理。

9.2 objective-C 2.0是怎樣一個記憶體機制?

   在objective-C 2.0語言中,記憶體管理主要是基於一個 release count的值來進行判斷系統是否要回收該記憶體。當某對象的 retain count等於0時,系統則會回收這段記憶體。所以當我們想要釋放掉某項目時,我們只需要使其retain count等於0即可。當我們想要hold住該段記憶體以便後面繼續使用(具體怎麼用將會在後面提到)那麼你只需要保證在你要使用它之前 它的retain count>0即可。為何蘋果要這樣做?等下告訴你。

   首先還是說明 retain count是如何去操作的。假設我們有一個class A:NSObject,然後我們聲明一個變數  A *a,不用在意它是臨時變數還是類屬性變數,這時候它的retain count等於0;當我們給這個變數建立記憶體空間的時候 我們會使用NSObject類的 alloc 函數:a=[A alloc];這時候 a的retain count則會+1,能使 retain count +1的函數不止有alloc,還有 [a retain],和[a copy],關於這兩個函數會在什麼時候使用以及他們的區別,將在後面討論。要想使retain count -1 你需要調用函數 [a release];那麼寫一串代碼來直觀的表示retain count的變化:

#import "A.h"

/** 略**/

-(void) retainCountDemo
{
   A *a;                   //retain count of a is 0  a = [A alloc];           //retain count of a is 1
  [a retain];              //retain count of a is 2
  [a release];             //retain count of a is 1
  A* a1 = [a copy];      //retain count of a1 is 1,and a's is 1 too
  [a release];             //retain count of a is 0, and it will be dealloced
  [a1 release];            //retain count of a1 is 0, and it will be dealloced
  return;
}

 

9.3 copy 和 retain的區別?

     copy和retain的區別在於它們的字面意思,不同之處在於一個是直接引用(比如說對象的引用),然後retain count+1,另外一個是複製使用(比如說字串的使用),將複製到的對象a1的retain count+1.

9.4 他們有什麼用?

     objective-C 2.0是一門物件導向的語言,通過使用 retain count來就可以讓開發人員在各自的模組中建立使用以後就“釋放”,而不用擔心影響到其他模組如果同時會使用到該變數而造成的crash。最典型也是最常用的就是我們的NSURLConnection類裡面的request,這種非同步請求,你並不知道什麼時候該釋放,因為你沒法判斷什麼時候請求能夠返回,所以通過使用retain count 你只關心你建立了一個 NSURLConnction,在設定完接收對象,發送完請求以後你就可以release掉它了,而無需關心記憶體泄露之類的問題。因為在發送請求的時候,NSURLConnction會將自己retain一次,這時候的retain count變為2,你在自己的函數中調用release的時候retaincount則變為1,而當該請求返回的時候,完成回呼函數,會自動調用release一次,這時候NSURLConnction的retain count變為0而釋放掉。

    通過上面的例子來總結,我們可以發現,其實這是一種延遲釋放的機制(好吧,這個詞是我自己想到的)。依照這個我們可以解決很多個物件共用而不知道該誰去管理記憶體的問題,蘋果的做法就是:管好你自己,你自己alloc+retain多少次,那麼請你release多少次。所以,記憶體管理最基本的就是管好你自己!

9.5 記憶體管理有沒有更簡單點的方法呢?

     有!但是不建議使用。

    方法1:autorelease函數,通過函數名你應該可以知道這個是幫你自動release的。但是需要注意的是這個函數只會自動幫你release1次,你如果在中間使用了retain之類的,所以還請手動release。同時這個有一個致命的缺點,你想用autorelease在class A中建立對象然後傳遞給class B使用的話這是非常危險的,autorelease是基於系統內建的自動釋放池來進行記憶體管理,系統會每隔一段時間去檢測施放池中的對象,並且釋放不在使用的對象。當你傳遞給B的時候,還沒來得及使用,被自動釋放掉了,那麼你的程式又會crash。所以 autorelease通常都是在局部對象中使用。

    方法2:IOS 5 ARC(Automatic Reference Counting),蘋果終於發現了做IOS開發有太多無證程式猿了,經常因為記憶體釋放不好而導致野指標,記憶體泄露,各種問題的存在。所以蘋果在IOS5的SDK中加了這麼一個東西,自動引用計數器。好了,這下各位可以放心的使用,而不用麻煩的去數retain release了。如果你能保證你的客戶都會乖乖升級到IOS5的話…… 顯然,暫時這東西還不太靠譜……

9.6 稍微進階點的應用:

     於是我就只想到一個大量產生的臨時對象和自動釋放池這兩個名詞,具體如何使用,請去查閱蘋果API,keywords:NSAutoreleasePool。

  

9.7 後記:

     上面所寫都是我自己對Objective-C的理解和自己以前所犯錯誤而總結出來的經驗,遺憾的是正好我高考語文考試不及格,所以寫的文章也不太好懂,還請見諒,如果有什麼疑問或者意見,還請指出一起討論學習。執行個體代碼,非常簡單,如果有朋友看了也不太明白,還請自己寫demo驗證。對於委託(delegate),通知(notification),屬性等這些東西本來是想也在這裡說一說的,但是因為思維跳躍比較大,所以還是抽時間另外寫出來。

相關文章
阿里云产品大规模降价
  • 最高幅度達59%,平均降幅23%
  • 核心產品降價
  • 多地區降價
undefined. /
透過 Discord 與我們聯繫
  • 安全、匿名的群聊,不受干擾
  • 隨時了解活動、活動、新產品等訊息
  • 支持您的所有問題
undefined. /
免費試用
  • 開啟從ECS到大數據的免費試用之旅
  • 只需三步 輕鬆上雲
  • 免費試用ECS t5 1C1G
undefined. /

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.