小小ARC造福無數碼農

今天無心中看到很是久以前的一個項目,古老的語法規範,還有更讓人戰戰兢兢「內存管理代碼」!

在這不得不說OC中內存管理的三種分類: 設計模式

  • Mannul Reference Counting(MRC,手動管理,在開發iOS5.0以前的版本號的項目時咱們要本身負責使用引用計數來管理內存,比方要手動retain、release、autorelease 等,而在其後的版本號可以使用ARC,讓系統本身管理內存。post

    )ui

  • Automatic Reference Counting(ARC,本身主動引用計數,iOS5.0 以後推出的)spa

  • Garbage Collection(垃圾回收)。設計

    iOS不支持垃圾回收; ARC做爲蘋果新 供的技術,蘋果推薦開發人員使用ARC技術來管理內存;指針

    那麼今天就着重探討一下ARC!!!code

    一、什麼是ARC?

      Automatic Reference Counting,本身主動引用計數,即ARC,可以說是WWDC2011和iOS5所引入 的最大的變革和最激動人心的變化。ARC是新的LLVM 3.0編譯器的一項特性,使用ARC,可以說一舉攻克了廣大iOS開發人員所憎恨的手動內存管理的麻煩。對象

      在project中使用ARC很easy:僅僅需要像往常那樣編寫代碼,僅僅只是永遠不寫retain,release和 autorelease三個keyword就好,這是ARC的基本原則。內存

      當ARC開啓時,編譯器將本身主動在代碼合適的地方插入retain, release和autorelease,而做爲開發人員,全然不需要操心編譯器會作錯(除非開發人員本身錯用ARC了)。開發

      手動管理內存, 可以簡稱MRC (Manual Reference Counting)   

      ARC與其它語言的」垃圾回收」機制不一樣。
      ARC:編譯器特性
      「垃圾回收」:執行時特性

    二、ARC工做原理及推斷準則

      ARC是Objective-C編譯器的特性,而不是執行時特性或者垃圾回收機制,ARC所作的僅僅只是是在代碼編譯時爲你本身主動在合適的位置插入release或autorelease

    ARC的對象回收推斷準則:

    僅僅要沒有強指針指向對象,對象就會被釋放。

     

    注意:當使用ARC的時候,臨時忘記「引用計數器」,因爲推斷標準變了。

    三、指針分類

    1) 強指針:默認的狀況下,所有的指針都是強指針,keyword__strong
    2) 弱指針:__weakkeyword修飾的指針

    聲明一個弱指針例如如下: 

    __weak Person *p;

    四、ARC機制圖解

    NSString *firstName = @"OneV";

    這個時候firstName持有了@"OneV"。



      固然,一個對象可以擁有不止一個的持有者(這個相似MRC中的retainCount>1的狀況)。

    在這個樣例中顯然self.textField.text也是@「OneV",那麼現在有兩個指針指向對象@"OneV」(被持有兩次,retainCount=2,事實上對NSString對象說retainCount是有問題的,只是anyway~就這個意思而已.)。   過了一下子,或許用戶在textField裏輸入了其它的東西,那麼self.textField.text指針顯然現在指向了別的字符串,比方@「onevcat",但是這時候原來的對象已然是存在的,因爲另外一個指針firstName持有它。
    現在指針的指向關係是這種:

      僅僅有當firstName也被設定了新的值,或者是超出了做用範圍的空間(比方它是局部變量但是這個 方法運行完了或者它是實例變量但是這個實例被銷燬了),那麼此時firstName也再也不持有 @「OneV",此時再也不有指針指向@"OneV",在ARC下這樣的情況發生後對象@"OneV"即被銷燬,內存釋放。   
      相似於firstName和self.textField.text這種指針使用keywordstrong進行標誌,它意味着僅僅要該指針指向某個對象,那麼這個對象就不會被銷燬。

    反過來講,ARC的一個基本規則便是,僅僅要某個對象被任一strong指針指向,那麼它將不會被銷燬。假設對象沒有被不論什麼strong指針指向,那麼就將被銷燬。
      在默認狀況下,所有的實例變量和局部變量都是strong類型的。可以說strong類型的指針在行爲上和MRC時代retain的property是比較類似的。 

      既然有strong,那確定有weak咯~,weak類型的指針也可以指向對象,但是並不會持有該對象。
      比方:

      __weak NSString *weakName = self.textField.text

    獲得的指向關係是:

      這裏聲明瞭一個weak的指針weakName,它並不持有@「onevcat"。假設self.textField.text的內容發生改變的話,依據以前提到的"僅僅要某個對象被任一strong指針指向,那麼它將不會被銷燬。假設對象沒有被不論什麼strong指針指向,那麼就將被銷燬」原則,此時指向@「onevcat"的指針中沒 有strong類型的指針,@"onevcat"將被銷燬。

     

      同一時候,在ARC機制做用下,所有指向這個對象的weak指針將被置爲nil。這個特性至關實用,相信無數的開發人員都之前被指針指向已釋放對象所形成的EXC_BAD_ACCESS困擾過,使用ARC之後,不管是strong仍是weak類型的指針,都再也不會指向一個dealloced的對象,從根源上攻克了意外釋放致使的crash。

      只是在大部分狀況下,weak類型的指針可能並不會非常常常使用。比較常見的使用方法是在兩個對象間存在包括關係時:對象1有一個strong指針指向對象2,並持有它,而對象2中僅僅有一個weak指針指回對象1,從而避免了循環持有。

     

      一個常見的樣例就是oc中常見的delegate設計模式,viewController中有一個strong指針指向它所負責管理的UITableView,而UITableView中的dataSource和delegate指針都是指向viewController的weak指針。

    可以說,weak指針的行爲和MRC時代的assign有一些類似點,但是考慮到weak指針更聰明些(會本身主動指向nil),所以仍是有所不一樣的。 


    經過上面的圖解。你們必定對ARC底層的處理機制有更深的認識了吧!

    歡迎你們提出補充哦。

相關文章
相關標籤/搜索