Block原理(二)- 用白話說說底層源碼,不扯代碼

之前有一篇關(guān)于block的源碼探究分析 Block原理(一),時至今日,總覺的那篇文章說得不夠流暢,今天打算從頂層設(shè)計的角度試著拆解下block的設(shè)計思想,拗腦的源碼部分就不必再次觸碰了,盡量保障這篇文章閱讀下來不會感覺不舒服

block的頂層結(jié)構(gòu)

摒棄圖文,最主要的是能說得明白,而不是看得明白,一些關(guān)鍵名字我代替源碼中的復雜命名,用別名代替,姑且往后看,后面會拆解為什么要這樣指代別名

先從最全的結(jié)構(gòu)說起,也就是 block捕獲 __block 修飾的變量說起

注意層級關(guān)系,縮進的表示 屬于上一層級

  • Block_Struct (我起的別名,為了指代方便)
    • Block_ByRef (用__block 修飾的變量就會產(chǎn)生這個結(jié)構(gòu))
      • forwarding (指向一塊堆空間,后面會拆解)
      • var_ptr (捕獲的變量,是個指針)
    • Block_Layout
      • isa (block類別,GlobalBlock/StackBlock/MallocBlock)
      • func_ptr (函數(shù)入口指針,就是上層代碼中那個 {} 部分了)

Block_Struct這個結(jié)構(gòu) 就是block的精髓了

  1. 首先會在棧上構(gòu)建一個這樣的結(jié)構(gòu)

    構(gòu)造 Block_ByRef

    Block_ByRef 捕獲變量 var(__block修飾的變量), var_ptr 捕獲的是 var的指針

    構(gòu)造 Block_Layout

    isa 為 StackBlock(也就是棧block)

    func_ptr 指向 函數(shù)入口,也就是執(zhí)行{}部分的入口函數(shù)地址

以上都是??臻g上的行為

一旦 上層代碼中存在 block傳參, 就會

  1. 堆上開辟空間 (注意: 開辟空間 發(fā)生在堆上)

    構(gòu)造 Block_ByRef

    var_ptr = 棧Block_ByRef.var_ptr (棧上的值賦值過來)

    棧Block_ByRef 中的 forwarding 指向 這個 堆Block_ByRef 空間

    forwarding 也指向 自己這個 堆Block_ByRef 空間 (細細品一下)

構(gòu)造 Block_Layout

isa = MallocBlock (也就是堆block)

func_ptr = 棧Block_ByRef.func_ptr

上層代碼中block的暗行為

上層語言中使用block,經(jīng)常會傳參,這個傳參的過程 就是 Block_Struct 的拷貝過程

但不是單純的Block_Struct指針拷貝,而是棧上額外創(chuàng)建一個 Block_Struct 結(jié)構(gòu)

新創(chuàng)建的 Block_Struct 成員Block_Byref是塊堆內(nèi)存 (把棧上的 var_ptr 拷貝到這個堆內(nèi)存上, forwarding 指向 這塊堆內(nèi)存)

成員 Block_Layout 也指向堆空間 (把棧上的 func_ptr 拷貝過來)

如此 導致什么樣的效果

在上層高級語言中,表現(xiàn)出來就是

在block內(nèi)部訪問 block外定義的變量, 與在block外部訪問 變量,能訪問到同一個,

區(qū)別就是,外部是在棧上訪問, 內(nèi)部是在堆上訪問

外部訪問 - 棧A:Block_Struct -> 棧A:Block_Byref(棧) -> forwarding -> 堆空間 -> 變量var指針

內(nèi)部訪問 - 棧B:Block_Struct -> 棧B:Block_Byref(堆) -> forwarding -> 堆空間 -> 變量var指針

最終 訪問到了同一塊 堆內(nèi)存, 無論內(nèi)部還是外部,訪問修改的都是同一塊內(nèi)存,所以就沒什么問題了

block體執(zhí)行

block定義之后,關(guān)鍵還是要執(zhí)行的

在當前的棧Block_Layout里調(diào)用 func_ptr, 與 被拷貝到別處的 堆Block_Layout 里調(diào)用 func_ptr 效果也是一樣的,不管在哪兒調(diào)用,func_ptr 入口函數(shù)地址 都是那一個

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

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

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