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

循環(huá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;
}

運行結(jié)果如下

image.png
解決循環(huán)引用問題 - ARC
  • 用__weak、__unsafe_unretained解決
    • __weak:不會產(chǎn)生強引用,指向的對象銷毀時,會自動讓指針置為nil
    • __unsafe_unretained:不會產(chǎn)生強引用,不安全,指向的對象銷毀時,指針存儲的地址值不變
image.png

代碼佐證

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // __weak:不會產(chǎn)生強引用,指向的對象銷毀時,會自動讓指針置為nil
        // __unsafe_unretained:不會產(chǎn)生強引用,不安全,指向的對象銷毀時,指針存儲的地址值不變
        
        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;
}

運行結(jié)果

__block.png
解決循環(huá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;
}

運行結(jié)果如下

image.png

面試題 - Block

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

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

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

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

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

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

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


項目演示代碼
iOS-block-cycle


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

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

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

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

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

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

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

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