Block溫顧

來著唐巧的技術(shù)博客

閱博筆記,助于記憶和回顧

什么是block

In programming languages, a closure is a function or reference to a function together with a referencing environment—a table storing a reference to each of the non-local variables (also called free variables or upvalues) of that function.

閉包是一個函數(shù)或者想象一個函數(shù)指針,它擁有一個函數(shù)執(zhí)行時的上下文(自己認(rèn)為是函數(shù)執(zhí)行時的外部變量)

block的內(nèi)部數(shù)據(jù)結(jié)構(gòu)

struct Block_descriptor {
    unsigned long int reserved;
    unsigned long int size;
    void (*copy)(void *dst, void *src);
    void (*dispose)(void *);
};

struct Block_layout {
    
    void *isa; //isa指針,所有對象都有的指針,用于實現(xiàn)對象相關(guān)的功能
    int flags; //用于按bit位表示一些block的附加信息
    int reserved;//保留變量
    void (*invoke)(void *, ...);//函數(shù)指針,指向具體的block實現(xiàn)的函數(shù)調(diào)用地址
    struct Block_descriptor *descriptor;//表示該 block 的附加描述信息,主要是 size 大小,以及 copy 和 dispose 函數(shù)的指針
    /* Imported variables. */  //block可以訪問它的局部變量,將需要在函數(shù)中用到的外部變臉復(fù)制到了結(jié)構(gòu)體中
    
};

block的三種類型

  • _NSConcreteGlobalBlock 全局的靜態(tài) block,不會訪問任何外部變量。
  • _NSConcreteStackBlock 保存在棧中的 block,當(dāng)函數(shù)返回時會被銷毀。
  • _NSConcreteMallocBlock 保存在堆中的 block,當(dāng)引用計數(shù)為 0 時會被銷毀。

當(dāng)不訪問外部任何變量時

MRC環(huán)境下block類型是_NSConcreteStackBlock
ARC環(huán)境下block類型是_NSConcreteGlobalBlock。

當(dāng)訪問外部變量時

MRC環(huán)境下block類型是_NSConcreteStackBlock
ARC環(huán)境下block類型是_NSConcreteMallocBlock

訪問的外部變量時,其實是拷貝了外部的變量,所以改變block實現(xiàn)體時的外部變量,并不會對外部變量造成影響

在ARC中其實在block創(chuàng)建時就會默認(rèn)執(zhí)行block copy,這時block就會從棧區(qū)拷貝到堆區(qū),而block的類型也會從_NSConcreteStackBlock變成_NSConcreteMallocBlock

__block

當(dāng)引用的外部變量是由__block 修飾的時候,那么block內(nèi)部就會復(fù)制外部變量的地址而不是值了。而且如果你沒有用修飾__block,那么你只能使用這些“變量”,而不能修改他

__block和__weak的區(qū)別

  1. __block不管是ARC還是MRC模式下都可以使用,可以修飾對象,還可以修飾基本數(shù)據(jù)類型。
  1. __weak只能在ARC模式下使用,也只能修飾對象(NSString),不能修飾基本數(shù)據(jù)類型(int)。
  2. __block對象可以在block中被重新賦值,__weak不可以。
  3. __block對象在ARC下可能會導(dǎo)致循環(huán)引用,非ARC下會避免循環(huán)引用,__weak只在ARC下使用,可以避免循環(huán)引用。

__block其實就是拷貝了外部變量的地址,在ARC下,就很有可能會引起循環(huán)引用了,self擁有block,而block擁有self。這時在block實現(xiàn)體內(nèi)self會被retain,但是在·MRC時__block修飾的self在則不會被retain。
所以在ARC環(huán)境下循環(huán)引用的地方還是用__weak比較安全

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

  • 《Objective-C高級編程》這本書就講了三個東西:自動引用計數(shù)、block、GCD,偏向于從原理上對這些內(nèi)容...
    WeiHing閱讀 10,101評論 10 69
  • 前言 Blocks是C語言的擴充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了這...
    小人不才閱讀 3,869評論 0 23
  • 一、Objective-C發(fā)展史 Objective-C從1983年誕生,已經(jīng)走過了30多年的歷程。隨著時間的推移...
    沒事蹦蹦閱讀 6,001評論 12 34
  • Block 梳理與疑問 時隔一年,再次讀 《Objective-C 高級編程》,看到 block 一章,這一次從頭...
    DeerRun閱讀 751評論 0 2
  • 概述閉包,可以捕獲代碼。block對象常量塊外的屬性 非標(biāo)準(zhǔn)c組成部分。源碼部分不粘了 - 主要證明兩點 1 是個...
    zx1798閱讀 807評論 1 2

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