block解決循環(huán)引用詳細解釋

一暴构、產(chǎn)生原因

網(wǎng)上大部分帖子都表述為:"block里面引用了self導致循環(huán)引用"常遂,會讓大家理解為要顯式地出現(xiàn)"self"就會引起循環(huán)引用找田。其實這種說法是很不嚴謹?shù)摹?/p>

下面用代碼來說明:
*1 聲明幾個block和一個屬性:

@interface ViewController (){
void(^myBlock1)(void);
void(^myBlock2)(void);
void(^myBlock3)(void);
 }
@property (nonatomic,copy) NSString *person;
@end

*2 使用weakSelf 不會 引起循環(huán)引用(以下是最常用但是不提倡方法毒姨,后面會提到原因冤竹,繼續(xù)看下去哦):

__weak typeof(self) weakSelf = self;

NSLog(@"init--> value:%@,address=%p,self=%p",self.person,self.person,self);
  myBlock1 = ^(void){
//這樣不會造成循環(huán)引用
NSLog(@"execute1--> value:%@,address=%p,weakSelf=%p",weakSelf.person,weakSelf.person,weakSelf);
 };

*3 直接使用self,會循環(huán)引用:Xcode會給警告

myBlock2 = ^(void){
//這樣造成循環(huán)引用
NSLog(@"execute2--> value:%@,address=%p,self=%p",self.person,self.person,self);
};

*4 要執(zhí)行的方法抽取出來案铺,也不會循環(huán)引用:

 myBlock3 = ^(void){
//這樣也不會造成循環(huán)引用,已經(jīng)抽取出要執(zhí)行的方法
[weakSelf myBlock3Func];
 }; 
- (void)myBlock3Func{
NSLog(@"execute3--> value:%@,address=%p,self=%p",self.person,self.person,self);
 }

*5 block不是self的屬性或者變量時蔬芥,在block內(nèi)使用self也不會循環(huán)引用:

 //block不是self的屬性時,block內(nèi)部使用self也不是循環(huán)引用
 Animal *animal = [[Animal alloc] init];
 animal.animalBlock = ^(void){
 NSLog(@"animal-->    value:%@,address=%p,self=%p",self.person,self.person,self);
};

所以說并不是在block中使用self必定會循環(huán)引用红且,要分情況處理坝茎,如果產(chǎn)生了循環(huán)引用如何解決呢:

二涤姊、解決循環(huán)引用

*1 為了方便使用暇番,首先定義兩個宏

#ifndef weakify
#define weakify(o) __typeof__(o) __weak o##__weak_ = o;
     #define strongify(o) __typeof__(o##__weak_) __strong o =    o##__weak_;
#endif

*2 使用如下代碼解決循環(huán)引用

weakify(self);
success:^(AFHTTPRequestOperation *operation, id responseObject) {
    strongify(self);
    if (!self__weak_) return ;
   //...................
   }

3* 總結解釋上述代碼作用

  • weakify(self); 創(chuàng)建一個指向self的弱引用
  • strongify(self); 當加上修飾符strong時,當別處把“self”釋放掉思喊,但調(diào)用該“self”的block如果仍然沒有執(zhí)行結束壁酬,那么系統(tǒng)就會等待block執(zhí)行完成后再釋放,對該“self”在block中的使用起到了保護作用。當block執(zhí)行結束后會自動釋放掉舆乔。
  • if (!self__weak_) return ; ** 進行判斷岳服,如果在執(zhí)行strongify(self)之前“self已經(jīng)被釋放掉了,則此時self=nil希俩,所以直接return即可”**

三吊宋、 代碼驗證

*1 我們自定義一個類Text,在該類dealloc方法中加一行打印;

  -(void)dealloc{
 NSLog(@"dealloc %@被銷毀了Q瘴洹A选!A凵稀U馕恰!",[self class]);
}

*2 將Text作為另外一個類的屬性

 @property(nonatomic,strong)Text *text;

*3 測試結果

 Text *text=[[Text alloc]init];
  self.text=text;

weakify(_text);

 //開啟子線程      
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

        NSInteger count =0;

      strongify(_text);
     
        while( count<10) {

            count++;

            NSLog(@"---------%@---%ld",_text__weak_,(long)count);

            sleep(1);

        }

    });

 //3秒后將 text對象 銷毀
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3*NSEC_PER_SEC)),dispatch_get_main_queue(), ^{
        
        self.text=nil;
        
    });

4* 第一次篙议,不使用 strongify(_text);

屏幕快照 2016-04-21 下午9.46.30.png

5*第二次唾糯,使用 strongify(_text);


屏幕快照 2016-04-21 下午9.46.05.png

可以清楚的看到,添加了strongify(_text)鬼贱,系統(tǒng)就會等待block執(zhí)行完成后再釋放text對象移怯,該text對象在block中的使用起到了保護作用。當block執(zhí)行結束后會自動釋放掉

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末这难,一起剝皮案震驚了整個濱河市芋酌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌雁佳,老刑警劉巖脐帝,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異糖权,居然都是意外死亡堵腹,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門星澳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疚顷,“玉大人,你說我怎么就攤上這事禁偎⊥鹊蹋” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵如暖,是天一觀的道長笆檀。 經(jīng)常有香客問我,道長盒至,這世上最難降的妖魔是什么酗洒? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任士修,我火速辦了婚禮,結果婚禮上樱衷,老公的妹妹穿的比我還像新娘棋嘲。我一直安慰自己,他們只是感情好矩桂,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布沸移。 她就那樣靜靜地躺著,像睡著了一般侄榴。 火紅的嫁衣襯著肌膚如雪阔籽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天牲蜀,我揣著相機與錄音笆制,去河邊找鬼。 笑死涣达,一個胖子當著我的面吹牛在辆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播度苔,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼匆篓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了寇窑?” 一聲冷哼從身側(cè)響起鸦概,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎甩骏,沒想到半個月后窗市,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡饮笛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年咨察,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片福青。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡摄狱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出无午,到底是詐尸還是另有隱情媒役,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布宪迟,位于F島的核電站酣衷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏踩验。R本人自食惡果不足惜鸥诽,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一商玫、第九天 我趴在偏房一處隱蔽的房頂上張望箕憾。 院中可真熱鬧牡借,春花似錦、人聲如沸袭异。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽御铃。三九已至碴里,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間上真,已是汗流浹背咬腋。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留睡互,地道東北人根竿。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像就珠,于是被迫代替她去往敵國和親寇壳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容