iOS中循環引用的解除

一:爲何形成了循環引用??????????????????????????html

 

首先    安全

對於網絡工具類  finishedBlock裏面 的一個屬性是 copy的網絡

那麼 NetworkTools 會對網絡工具 finishedBlock進行一個強引用異步

 

左邊的控制器viewController裏面 工具

 viewController 對 NetworkTools對象 tools進行強引用 spa

 

在右邊有一個 self.finishedBlock = finished 的賦值3d

 

在左邊的self.view     而後呢      self.finishedBlock = finished  這個對self.view指針

進行一個強引用    htm

 

形成了一個閉環  finishedBlock(引用)----self.view()--(self就是那個控制器器 對NetworkTools對象 tools強引用)----tools(引用了)finshedBlock對象

 

產生了一個閉環  形成了一個封閉的強引用 

 

 

--------結果是誰釋放不了

 

 

 

 

二:如何去打斷循環引用?????????????????????????

 

 方式1:--打斷引用鏈條         方式2:--使用__weak  

 

方式1: 能夠在左邊的控制器viewcontroller裏面去作一個動做

把那個 self.tools改爲一個

NetworkTools * tools  讓tools成爲一個局部的變量    懂?????

他天然在走出了做用域就會自動釋放了    打破了上面的環節   沒有了self.view

那個控制器的對他的強引用

這個就是破壞引用鏈條的原理

 

 

 

方式2: 在

 

 

在左邊添加了

  // 方式2

    __weak typeof(self) weakSelf = self;

    

    [self.tools lodaData:^(NSString *html) {

        NSLog(@"%@ %@",html,weakSelf.view);

    }];

添加了這樣的東西的話  咱們就能夠的接觸循環引用的

 這個引用鏈條也會被破壞掉    破壞是在那個   finishedBlock 對self.view的那個環節

 

 

 

整體思路的是:打破循環引用環節的任何一環就行

 

 

方法3: 使用__unsafe_unretained typeof(self) weakSelf = self;

//方法3

    __unsafe_unretained typeof(self)  weakSelf= self;

    [self.tools lodaData:^(NSString *html) {

        NSLog(@"%@ %@",html,weakSelf.view);

    }];

 

 

 

 

 

三:對__unsafe_unretained和 __weak的深度挖掘??????????????

 

咱們在網絡工具類裏面去的作一個耗時操做去模仿網絡請求延時操做

 

 __weak是iOS5.0的 

 

 

這個時候  weakSelf.view打印的是null  

若是異步操做沒有完成的話,他就會釋放控制器   __weak自己是弱引用

當異步操做執行完畢了的話 ,此時進行回到的時候  self已經被釋放了 沒法再去訪問屬性   也沒法調用方法  因此打印的是null

 

( 因此在點擊返回的快慢不一樣  打印結果不一樣)

 

 

 

用__unsafe_unretained的時候   __unsafe_unretained是iOS4.0推出的

 

 

 

 

程序就崩潰了     這個MRC的錯誤     壞內存訪問  野指針錯誤

__weak至關於 weak 不會作強引用      可是若是對象被釋放,執行地址會指向nil

 

MRC下面屬性的持有都是assign 不會作強引用  可是若是對象被釋放

          內存地址還不變  此時再去調用 就會出現野指針的訪問

 

因此在開發中通常去推薦__weak    __unsafe_unretained相對於不安全

 

 

還有一種流傳出來的代碼

(stringSelf強引用 對weakSelf進行強引用 本意 但願在執行完代碼了後 繼續執行回調)

 

可是若是的話__unsafe_unretained 換成這個  他仍是會崩潰的

 

 

整體的區別:

__weak  寫法的話  self 已經被釋放   只爲nil

__unsafe_unretained的話  self已經被釋放的話  就會出現野指針訪問

 

內部可使用 strongSelf    可是沒有深惡麼卵用  

相關文章
相關標籤/搜索