block 之 block的底層實現

前言

最近在總結關于block的東西,可能會寫幾篇關于block的博客,語法那些就不說,這里提供一個語法的入口,我們主要探究block的底層實現、block引用局部變量、block的內存管理,今天先講下block的底層實現。

block實例

#import <Foundation/Foundation.h>

void hello_(){
    int i = 2;
    int j = 3;
    long (^myBlock)(void) = ^long(){
        return i*j*10;
    };
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
 
    }
    return 0;
}

定義hello方法是方便我們等下查看編譯代碼的時候準確定位myBlock的實現。用clang將objected-C 代碼編譯為C++代碼。

控制臺命令:clang -rewrite-objc main.m 

我們打開main.cpp文件,定位到以下代碼:

struct __block_impl {
  void *isa;
  int Flags;
  int Reserved;
  void *FuncPtr;
};

這是block基類的定義,所有block都繼承于它,擁有它以下那些屬性:
isa是指向該block的類型的類,也就是我們理解的對象指針;
Flags包含了引用計數;
Reserved:保留變量,我的理解是表示block內部的變量數;
FuncPtr:函數指針,指向具體block實現的函數的調用地址;

struct __hello__block_impl_0 {
  struct __block_impl impl;
  struct __hello__block_desc_0* Desc;
  int i;
  int j;
  __hello__block_impl_0(void *fp, struct __hello__block_desc_0 *desc, int _i, int _j, int flags=0) : i(_i), j(_j) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

這是myBlock的定義,它的結構體以hello打頭,代表myBlock位于hello函數里,這是block的命名方式。__hello__block_desc_0指的是myBlock的描述。

static long __hello__block_func_0(struct __hello__block_impl_0 *__cself) {
  int i = __cself->i; // bound by copy
  int j = __cself->j; // bound by copy

        return i*j*10;
    }

myBlock內函數的具體實現,注意bound by copy,block對外部引用變量做只讀拷貝,還有另外的一種情況,在以后講到關于block引用局部變量的時候會說。

static struct __hello__block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __hello__block_desc_0_DATA = { 0, sizeof(struct __hello__block_impl_0)};

這是myBlock的具體描述

void hello_(){
    int i = 2;
    int j = 3;
    long (*myBlock)(void) = ((long (*)())&__hello__block_impl_0((void *)__hello__block_func_0, &__hello__block_desc_0_DATA, i, j));
}

myBlock實例變量的定義

做下小小總結

block是對象;
編譯器會根據block捕獲的局部變量,生成具體的結構體定義。block內部的代碼將會提取出來,成為一個單獨的C函數(eg:__hello__block_func_0)。創(chuàng)建block時,實際就是在方法中聲明一個struct,并且初始化該struct的成員。而執(zhí)行block時,就是調用那個單獨的C函數,并把該struct指針傳遞過去;
block中包含了被引用的局部變量(由struct持有),也包含了控制成分的代碼塊(由函數指針持有),符合閉包(closure)的概念。

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

相關閱讀更多精彩內容

  • 前言 Blocks是C語言的擴充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了這...
    小人不才閱讀 3,881評論 0 23
  • Block使用場景,可以在兩個界面的傳值,也可以對代碼封裝作為參數的傳遞等。用過GCD就知道Block的精妙之處。...
    Coder_JMicheal閱讀 824評論 2 1
  • iOS代碼塊Block 概述 代碼塊Block是蘋果在iOS4開始引入的對C語言的擴展,用來實現匿名函數的特性,B...
    smile刺客閱讀 2,468評論 2 26
  • 原文地址:Objective-C中的Block 1.相關概念 在這篇筆記開始之前,我們需要對以下概念有所了解。 1...
    默默_David閱讀 460評論 0 1
  • 《Objective-C高級編程》這本書就講了三個東西:自動引用計數、block、GCD,偏向于從原理上對這些內容...
    WeiHing閱讀 10,105評論 10 69

友情鏈接更多精彩內容