從堆棧剖析block

下面的講解均是在MRC下進(jìn)行,首先,需設(shè)置-fno-objc-arc。

兩概念


  • 內(nèi)存需要手動(dòng)分配(malloc)和銷毀(free)。

  • 一個(gè)線程會(huì)分配一個(gè)stack,里面包含這個(gè)函數(shù)參數(shù),局部變量,返回地址等信息。當(dāng)函數(shù)返回后,棧會(huì)被銷毀,有系統(tǒng)操作。 后面再去retain和copy是無效的。
    棧對(duì)象有速度的優(yōu)勢(shì),不會(huì)發(fā)生內(nèi)存泄漏,

存儲(chǔ)區(qū)域

通過查看block的isa值,可以看到以下3個(gè)名詞:

  • NSGlobalBlock 全局
  • NSStackBlock 棧
  • NSMallocBlock 堆

代碼演示

//全局block
- (dispatch_block_t)testGlobalBlock {
    dispatch_block_t block = ^(){
        NSLog(@"global block");
    };
    return block;
//或
//    return [block copy];//仍是全局    
}

//棧block
- (dispatch_block_t)testStackBlock {
    __block NSInteger i = 0;
    dispatch_block_t block = ^() {
        NSLog(@"%ld", ++i);
    };
    return block;
}
dispatch_block_t block = [self testStackBlock];
block(); 會(huì)crash
dispatch_block_t copyBlock = [block copy];
copyBlock(); 依然crash
//堆 block
- (dispatch_block_t)testMallocBlock {
    __block NSInteger i = 0;
    dispatch_block_t block = ^() {
        NSLog(@"%ld", ++i);
    };
    return [block copy];
}
  • 全局,不訪問外部任何變量,copy后仍是全局block;
  • 棧,block里有訪問外部變量,函數(shù)返回后立即銷毀,即使后面strong和copy都會(huì)crash;
  • 堆,有棧block拷貝過來,就和OC對(duì)象一樣,可訪問外部變量;

block為什么不用strong

@property (nonatomic, strong) NSString *testStr;
@property (nonatomic, strong) dispatch_block_t strongBlock;

testStr = @"aaa";
- (void)testStackBlock {
    __block NSInteger i = 0;
    //注意此處是self.而不是_strongBlock
    self.strongBlock = ^() {
        NSLog(@"%ld", ++i);
        NSLog(@"%@", _testStr);
    };
    self.copyBlock = ^() {
        NSLog(@"%ld", ++i);
        NSLog(@"%@", _testStr);
    };
}


[self testStackBlock];
_strongBlock(); //堆
_copyBlock(); //堆

棧blog不能訪問全局對(duì)象,只有堆blog。因?yàn)閟trong和copy均是copy,從語(yǔ)義上更貼切

ARC

在ARC下,即使你聲明的修飾符是strong,實(shí)際上效果是與聲明為copy一樣的。因此在ARC情況下,創(chuàng)建的block仍然是NSStackBlock類型,只不過當(dāng)block被引用或返回時(shí),ARC完成了copy和內(nèi)存管理的工作。

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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