【iOS 開發(fā)】為什么要用copy修飾Block

引用別人十個(gè)字對(duì)棧和堆的總結(jié)

棧是吃了吐 堆是吃了拉

下面進(jìn)入主題為什么要用copy去修飾block呢

個(gè)人理解:默認(rèn)情況下,block會(huì)存檔在棧中(棧是吃了吐),所以block會(huì)在函數(shù)調(diào)用結(jié)束被銷毀,在調(diào)用會(huì)報(bào)空指針異常,如果用copy修飾的話,可以使其保存在堆區(qū)(堆是吃了拉) ,它的生命周期會(huì)隨著對(duì)象的銷毀而結(jié)束的。只要對(duì)象不銷毀,我們就可以調(diào)用在堆中的block。

在了解block為什么要用copy之前,我們要先了解block的三種類型
NSGlobalBlock:全局的靜態(tài)block 沒有訪問外部變量 你的block類型就是這種類型(也就是說你的block沒有調(diào)用其他外部變量)
NSStackBlock:保存在棧中的block,沒有用copy去修飾并且訪問了外部變量,你的block類型就是這種類型,會(huì)在函數(shù)調(diào)用結(jié)束被銷毀 (需要在MRC)
NSMallocBlock 保存在堆中的block 此類型blcok是用copy修飾出來的block 它會(huì)隨著對(duì)象的銷毀而銷毀,只要對(duì)象不銷毀,我們就可以調(diào)用的到在堆中的block。

下面代碼演示

第一種全局的block 這種block不訪問外部的變量,我們?cè)陂_發(fā)中block都會(huì)訪問外部的變量,所以這種block開發(fā)不會(huì)用到,作為一個(gè)了解

void(^testOneBlock)() = ^(){
        NSLog(@"我是全局的block");
    };
    NSLog(@"testOneBlock=%@",testOneBlock);
  //控制臺(tái)輸出
  2017-06-10 09:45:09.767 ReactiveCocoa[871:14517] 
  testOneBlock=<__NSGlobalBlock__: 0x1045982d0>//全局block  他會(huì)隨程序銷毀而銷毀

第二種棧區(qū)block 這種block訪問外部變量,我們重點(diǎn)了解的是第二種和第三種,但是必須要在MRC的模式下控制臺(tái)才會(huì)輸出NSStackBlock類型
如何把當(dāng)前類改為MRC:Build phases -> Compile Sources -> 雙擊當(dāng)前類會(huì)彈出輸入框 -> 把-fno-objc-arc復(fù)制粘貼進(jìn)去 -> OK

   //需要MRC模式
    int a = 5;
    void(^testTwoBlock)() = ^(){
        NSLog(@"%d",a);
    };
    NSLog(@"testTwoBlock=%@",testTwoBlock);
    //控制臺(tái)輸出
    2017-06-10 09:45:09.768 ReactiveCocoa[871:14517]
    testTwoBlock=    <__NSStackBlock__: 0x7fff5b668770>//棧區(qū)block 函數(shù)調(diào)用完畢就會(huì)銷毀
    [testTwoBlock copy] 這樣操作就會(huì)變成堆區(qū)block

第三種堆區(qū)block 這種block是用copy去修飾的 它的生命周期會(huì)隨對(duì)象銷毀而銷毀

int a = 5;
self.block1 = ^(NSString *str, UIColor *color){
        NSLog(@"%d",a);
    };
    NSLog(@"block1=%@",self.block1);
//控制臺(tái)輸出
2017-06-10 10:02:35.107 ReactiveCocoa[1075:19674] block1=<__NSMallocBlock__: 0x60000004ee50>//用copy修飾的不會(huì)函數(shù)調(diào)用完就結(jié)束,隨對(duì)象銷毀才銷毀 這種是在開發(fā)中正確使用block的姿勢(shì)

第三種block在有些情況下會(huì)造成block的循環(huán)引用,我會(huì)寫在下一篇文章中

寫簡(jiǎn)書只是當(dāng)作筆記來寫,如果那里使用的姿勢(shì)不正確呢,歡迎大神來教導(dǎo)正確姿勢(shì)
(我是一個(gè)小菜逼,沒事就是愛裝逼)沒有特別的意思 純屬覺得順口。辛苦啦都看完啦

最后編輯于
?著作權(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)容

  • 前言 Blocks是C語(yǔ)言的擴(kuò)充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了這...
    小人不才閱讀 3,861評(píng)論 0 23
  • 《Objective-C高級(jí)編程》這本書就講了三個(gè)東西:自動(dòng)引用計(jì)數(shù)、block、GCD,偏向于從原理上對(duì)這些內(nèi)容...
    WeiHing閱讀 10,089評(píng)論 10 69
  • 本篇文章并不會(huì)剖析block的原理,筆者對(duì)原理也不甚了解。 聲明:對(duì)某個(gè)屬性的訪問(access)包括getter...
    VV木公子閱讀 1,205評(píng)論 1 18
  • Block 梳理與疑問 時(shí)隔一年,再次讀 《Objective-C 高級(jí)編程》,看到 block 一章,這一次從頭...
    DeerRun閱讀 749評(píng)論 0 2
  • 娃爸發(fā)現(xiàn)家邊上新開了家拉面館,看他的意思好像很想吃。我掂量了一下吃了一上午茶點(diǎn)的肚子,決定還是陪他去吃一碗。 拉面...
    菊上陽(yáng)光2閱讀 171評(píng)論 0 0

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