block自我理解1

从最简单的block开始开起,有一些浅显的心得如下:
在main.m文件生成如下代码:

int main(int argc, const char * argv[]) {
    void(^blk)(void) = ^{NSLog(@"Block");};
    blk();
}

通过命令行翻译(clang -rewrite-objc main.m)
删除不必要代码得到如下的c++文件

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

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_c8_pr2fhjtd5kz0_53s61zxc_400000gn_T_main_c32327_mi_0);
}

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[]) {
    void(*blk)(void) = ((void (*)())&__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA));
    ((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk);
    ((blk)->FuncPtr)(blk);
    return 0;
}

在block上的代码 翻译后 主要是变成了静态函数__main_block_func_0
从生成的代码上观察主要变成了封装的若干结构体
从上到下依次观察结构体,
__block_impl结构体是系统默认规定的结构体,并不是该代码翻译过来的结构体,结构体内部有isa指针(通常通俗的理解,拥有isa指针都会是一个对象,也就是说block会成为一个对象的可能,但这里不深究) ,观察最后一个变量
void FuncPtr; void 类似于oc中的id类型 (万能指针) 但从系统给出的变量名字可以看出是一个函数指针 也就是说oc中的block转换成多个结构体进行封装的函数指针
也就是说我们可以仿照转换的代码进行构造block
按照生成的代码风格进行 仿造后 得到如下代码:

struct __block_impl {
    void *FuncPtr;
};

struct __main_block_impl_0 {
    struct __block_impl impl;
    __main_block_impl_0(void *fp) {
        impl.FuncPtr = fp;
    }
};

static void __main_block_func_0() {
    NSLog(@"Block");
}

int main(int argc, const char * argv[]) {
    struct __main_block_impl_0 s = __main_block_impl_0((void *)__main_block_func_0);
    void(*blk)(void) = ((void (*)())&s);
    ((void (*)())((__block_impl *)blk)->FuncPtr)();
    return 0;
}

该代码是在原有代码的基础上 删除了多余结构体变量 尽量做到最简化实现,在main函数上 是保持了翻译后的代码风格,看上去有些乱,在此基础上写了一个更易理解的调用形式如下:

int main(int argc, const char * argv[]) {
    struct __main_block_impl_0 s = __main_block_impl_0((void *)__main_block_func_0);
    void(*blk)(void) = (void (*)())s.impl.FuncPtr;
    blk();
    return 0;
}

从上述描述上看,起码最简单的block ,最终也会形成一种函数,只不过是通过函数指针的形式进行调用,综上,可以通俗的理解为
block=函数+若干结构体封装(内部有函数指针变量)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Blocks Blocks Blocks 是带有局部变量的匿名函数 截取自动变量值 int main(){ ...
    南京小伙阅读 1,078评论 1 3
  • 《Objective-C高级编程》这本书就讲了三个东西:自动引用计数、block、GCD,偏向于从原理上对这些内容...
    WeiHing阅读 10,104评论 10 69
  • 前言 Blocks是C语言的扩充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了这...
    小人不才阅读 3,881评论 0 23
  • Block基础回顾 1.什么是Block? 带有局部变量的匿名函数(名字不重要,知道怎么用就行),差不多就与C语言...
    Bugfix阅读 6,909评论 5 61
  • 本文主要根据《Objective-C高级编程》这本书中的第二章来进行的一个总结,其中包含了查看其它文章后的总结和自...
    AnICoo1阅读 1,231评论 0 2

友情链接更多精彩内容