iOS-底層原理(11)-block-循環(huán)引用詳解

循環(huán)引用問(wèn)題
image.png

循環(huán)引用代碼例子如下

#import <Foundation/Foundation.h>

typedef void(^CSBlock)(void);
@interface Person : NSObject
/** age*/
@property(nonatomic,assign)int age;
/** blokc*/
@property(nonatomic,copy) CSBlock block;
@end

@implementation Person
- (void)dealloc {
    NSLog(@"%s",__func__);
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        person.age = 100;
        person.block = ^{
            NSLog(@"age = %d",person.age);
        };
    }
    NSLog(@"end");
    return 0;
}

運(yùn)行結(jié)果如下

image.png
解決循環(huán)引用問(wèn)題 - ARC
  • 用__weak、__unsafe_unretained解決
    • __weak:不會(huì)產(chǎn)生強(qiáng)引用,指向的對(duì)象銷(xiāo)毀時(shí),會(huì)自動(dòng)讓指針置為nil
    • __unsafe_unretained:不會(huì)產(chǎn)生強(qiáng)引用,不安全,指向的對(duì)象銷(xiāo)毀時(shí),指針存儲(chǔ)的地址值不變
image.png

代碼佐證

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // __weak:不會(huì)產(chǎn)生強(qiáng)引用,指向的對(duì)象銷(xiāo)毀時(shí),會(huì)自動(dòng)讓指針置為nil
        // __unsafe_unretained:不會(huì)產(chǎn)生強(qiáng)引用,不安全,指向的對(duì)象銷(xiāo)毀時(shí),指針存儲(chǔ)的地址值不變
        
        Person *person = [[Person alloc] init];
        person.age = 100;
//        __weak typeof(person) weakPerson = person;
        __unsafe_unretained typeof(person) weakPerson = person;
        person.block = ^{
            NSLog(@"age = %d",weakPerson.age);
        };
    }
    NSLog(@"end");
    return 0;
}
  • 用__block解決(必須要調(diào)用block)
image.png

代碼佐證

int main(int argc, const char * argv[]) {
    @autoreleasepool {
       // 法三 __block
        __block Person *person = [[Person alloc] init];
        person.age = 10;
        person.block = ^{
            NSLog(@"age is %d", person.age);
            person = nil;
        };
        person.block();
    }
    NSLog(@"end");
    return 0;
}

運(yùn)行結(jié)果

__block.png
解決循環(huán)引用問(wèn)題 - MRC
  • 用__unsafe_unretained解決(MRC環(huán)境下不支持__weak)
image.png
  • 用__block解決
image.png

代碼例子佐證

int main(int argc, const char * argv[]) {
    @autoreleasepool {
         // MRC環(huán)境下
        // MRC不支持__weak的
        __block Person *person = [[Person alloc] init];
        person.age = 10;
        person.block = ^{
            NSLog(@"age is %d", person.age);
        };
        [person release];
    }
    NSLog(@"end");
    return 0;
}

運(yùn)行結(jié)果如下

image.png

面試題 - Block

block的原理是怎樣的?本質(zhì)是什么?

封裝了函數(shù)調(diào)用以及調(diào)用環(huán)境的OC對(duì)象

__block的作用是什么?有什么使用注意點(diǎn)?
  • _block可以用于解決block內(nèi)部無(wú)法修改auto變量值的問(wèn)題
  • __block不能修飾全局變量、靜態(tài)變量(static)
  • 編譯器會(huì)將__block變量包裝成一個(gè)對(duì)象

注意:循環(huán)引用問(wèn)題

詳情請(qǐng)看iOS-block底層原理詳解之__block屬性

block的屬性修飾詞為什么是copy?使用block有哪些使用注意?
  • block一旦沒(méi)有進(jìn)行copy操作,就不會(huì)在堆上
  • 使用注意:循環(huán)引用問(wèn)題
block在修改NSMutableArray,需不需要添加__block?
  • 不需要

本文參考借鑒MJ的教程視頻,非常感謝.


項(xiàng)目演示代碼
iOS-block-cycle


更多block相關(guān)文章

iOS-block底層原理詳解-本質(zhì),類(lèi)型,copy屬性

iOS-copy底層原理之a(chǎn)uto變量

iOS-block底層原理詳解之__block屬性

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 上一篇文章iOS底層原理總結(jié) - 探尋block的本質(zhì)(一)中已經(jīng)介紹過(guò)block的底層本質(zhì)實(shí)現(xiàn)以及了解了變量的捕...
    xx_cc閱讀 11,086評(píng)論 8 54
  • OC語(yǔ)言基礎(chǔ) 1.類(lèi)與對(duì)象 類(lèi)方法 OC的類(lèi)方法只有2種:靜態(tài)方法和實(shí)例方法兩種 在OC中,只要方法聲明在@int...
    奇異果好補(bǔ)閱讀 4,532評(píng)論 0 11
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 30,286評(píng)論 8 265
  • 康熙大帝、絕對(duì)是中國(guó)歷史上一代英主。識(shí)人之能、用人之法也獨(dú)步天下!在于吳三桂的交量中、大膽啟用了落魄秀才周...
    心在路上走閱讀 387評(píng)論 0 1
  • 隨便想一想都知道,有些倉(cāng)促和草率了。 我用十幾分鐘從歡那里知道了機(jī)構(gòu),用幾分鐘修改了之前用過(guò)的簡(jiǎn)歷發(fā)去了一個(gè)陌生的...
    美麗之于你閱讀 283評(píng)論 0 0

友情鏈接更多精彩內(nèi)容