• Block原理


    •  Block原理
    •  Block自动截获局部变量

    Block原理

    #import <Foundation/Foundation.h>
    
    int main(int argc, const char * argv[]) {
        
        void (^blk)(void) = ^{
            printf("Block
    ");
        };
        
        blk();
        
        return 0;
    }
    clang -rewrite-objc main.m  //执行命令生成main.cpp

    主要代码摘要如下:

    // __block_impl
    struct __block_impl {
      void *isa;  
      int Flags;    // 标记
      int Reserved; // 今后版本升级所需要的区域
      void *FuncPtr;// 要调用的函数指针
    };
    // __main_block_impl_0即Block的结构体
    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; // _NSConcreteStackBlock相当于class_t结构体实例,联想OC对象中的isa指针的功能保持该对象对应的类的结构体,由此可见Block其实就是OC对象
        impl.Flags = flags;
        impl.FuncPtr = fp; 
        Desc = desc;
      }
    };
    // __main_block_func_0 
    static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
    
            printf("Block
    ");
        }
    // __main_block_desc_0
    static struct __main_block_desc_0 {
      size_t reserved;  // 今后升级所需要的区域 
      size_t Block_size;// block的大小
    } __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};
    
    int main(int argc, const char * argv[]) {
        /* 构造函数调用,去掉转换部分等价于
       struct
    __main_block_impl_0 *tmp = __main_block_impl_0(__main_block_func_0,&__main_block_desc_0_DATA);
       struct __main_block_impl_0 *blk = tmp; 栈上生成的结构体实例的指针tmp,赋值给结构体指针类型的变量blk
        */
        void (*blk)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
        /*
    去掉转换部分等价于
       (*blk->impl.FunPtr)(blk); 使用函数指针调用函数
      */ ((
    void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk); return 0; }

    源码下载

    Block自动截获局部变量

    1、什么是自动截获局部变量:在执行block语法的时候,block语法表达式所使用的局部变量被保存到block的结构体实例中(没有使用的变量不会被追加)。

    2、自动截获局部变量带来的问题:自动截获局部变量仅截获局部变量的值,block中在使用局部变量之后,在block结构体实例中重写该局部变量也不会改变原来截获的自动变量的值。

         

       

  • 相关阅读:
    Docker Compose实例
    Jenkins远程执行shell出现java: command not found
    SpringBoot之导入导出Excel
    在Jenkins中配置执行远程shell命令
    XJar: Spring-Boot JAR 包加/解密工具,避免源码泄露以及反编译
    Elasticsearch集成ik分词器
    AAAAAA
    Logstash-安装logstash-filter-multiline插件(解决logstash匹配多行日志)
    Elastic Kibana文档
    failed to create rwlayer: lstat /var/lib/docker/overlay2/ no such file or directory
  • 原文地址:https://www.cnblogs.com/imChay/p/6019477.html
Copyright © 2020-2023  润新知