Block(1)

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc xxx.m

block本质

以下是转换为c++之后的代码:

struct __block_impl {
  void *isa;
  int Flags;
  int Reserved;
  void *FuncPtr;
};
//block结构体
struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  //c++初始化(相当于OC中的init)
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

//block实际调用函数
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {

  NSLog((NSString *)&__NSConstantStringImpl__var_folders_m1_gnd8gfw115x69mr6xqg2yym00000gn_T_main_211f18_mi_0);
    }
//block的描述
static struct __main_block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};

int main(int argc, const char * argv[]) {
    //block变量
    //简化之后的代码
    block = &__main_block_impl_0(__main_block_func_0,&__main_block_desc_0_DATA);
    
    //调用block    
    //简化之后的代码
    (block->FuncPtr)(block);
    
    return 0;
}

block的本质为__main_block_impl_0 结构体中包含__block_impl__main_block_desc_0和一个构造函数,__main_block_impl_0结构体使用函数指针(__main_block_func_0)与描述结构体对象(__main_block_desc_0)初始化,这样__main_block_impl_0结构体就有了函数指针,当调用block时,从__main_block_impl_0中拿到函数指针,并将__main_block_impl_0结构体传入。

带参数的block

static void __main_block_func_0(struct __main_block_impl_0 *__cself, int a, int b) {

        NSLog((NSString *)&__NSConstantStringImpl__var_folders_m1_gnd8gfw115x69mr6xqg2yym00000gn_T_main_958cda_mi_0,a,b);
    }
    
int main(int argc, const char * argv[]) {

    block = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA));

    (block)->FuncPtr)(block, 10, 20);
    return 0;
}

使用外部局部变量的block

auto变量

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  int a;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _a, int flags=0) : a(_a) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
  int a = __cself->a; // bound by copy

        NSLog((NSString *)&__NSConstantStringImpl__var_folders_m1_gnd8gfw115x69mr6xqg2yym00000gn_T_main_259b79_mi_0,a);
    }

int main(int argc, const char * argv[]) {
    int a = 10;
    block = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA, a));

    (block->FuncPtr)(block);
    
    return 0;
}

static变量


struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  int *a;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int *_a, int flags=0) : a(_a) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
  int *a = __cself->a; // bound by copy

        NSLog((NSString *)&__NSConstantStringImpl__var_folders_m1_gnd8gfw115x69mr6xqg2yym00000gn_T_main_7bf366_mi_0,(*a));
    }


int main(int argc, const char * argv[]) {
    static int a = 10;
    block = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA, &a));

    (block->FuncPtr)(block);

    return 0;
}

使用外部全局变量的block

直接调用,无任何捕获


int a = 10;


struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {

        NSLog((NSString *)&__NSConstantStringImpl__var_folders_m1_gnd8gfw115x69mr6xqg2yym00000gn_T_main_10a4b4_mi_0,a);
    }


int main(int argc, const char * argv[]) {
    block = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA));

    (block->FuncPtr)(block);

    return 0;
}
You Might Also Like
发表评论