• 傻瓜学编程之block_2


    block的实质

    以一个简单的实现为列子;

    - (void)myBlcokTest{
        void (^blk)()=^{
            printf(@“beijinghuanyingni”);
        };
        blk();
    }
        
    

     终端:clang -rewrite-objc 类文件名.m

    cpp文件中关键代码:

        static void _I_People_myBlcokTest(People * self, SEL _cmd) {
            void (*blk)()=((void (*)())&__People__myBlcokTest_block_impl_0((void *)__People__myBlcokTest_block_func_0, &__People__myBlcokTest_block_desc_0_DATA));
            ((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk);
    
        }
        
    
        
        static void __People__myBlcokTest_block_func_0(struct __People__myBlcokTest_block_impl_0 *__cself) {
            printf("woshinidexiaodaye");
        }
        
    
        struct __People__myBlcokTest_block_impl_0 {  
            struct __block_impl impl;
            struct __People__myBlcokTest_block_desc_0* Desc;
            __People__myBlcokTest_block_impl_0(void *fp, struct __People__myBlcokTest_block_desc_0 *desc, int flags=0) {
                impl.isa = &_NSConcreteStackBlock;
                impl.Flags = flags;
                impl.FuncPtr = fp;
                Desc = desc;
            }
        };
        
    //    第一个成员
        struct __block_impl {
            void *isa;
            int Flags;
            int Reserved;
            void *FuncPtr;
        };
    //    第二个成员
        static struct __People__myBlcokTest_block_desc_0 {
            size_t reserved;// 升级版本所需要的区域
            size_t Block_size;//block大小
        } __People__myBlcokTest_block_desc_0_DATA = { 0, sizeof(struct __People__myBlcokTest_block_impl_0)};  
    

    运行时的myBlcokTest方法;

     static void _I_People_myBlcokTest(People * self, SEL _cmd) {
            
            void (*blk)()=((void (*)())&__People__myBlcokTest_block_impl_0((void *)__People__myBlcokTest_block_func_0, &__People__myBlcokTest_block_desc_0_DATA));
            
            ((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk);
    
     }
    

    去掉类型转化

    static void _I_People_myBlcokTest(People * self, SEL _cmd) {
            __People__myBlcokTest_block_impl_0 blk = __People__myBlcokTest_block_impl_0( __People__myBlcokTest_block_func_0, &__People__myBlcokTest_block_desc_0_DATA));
            
          、、、
        }

    __People__myBlcokTest_block_impl_0:是一个结构体 包含两个成员:

    struct __block_impl impl;
    struct __People__myBlcokTest_block_desc_0* Desc;

    以及一个构造函数:
    __People__myBlcokTest_block_impl_0(void *fp, struct __People__myBlcokTest_block_desc_0 *desc, int flags=0) 
    struct __People__myBlcokTest_block_impl_0 {  
        成员一:    struct __block_impl impl;   // __block_impl结构体
                      struct __block_impl {
                                 void *isa;
                                 int Flags;
                                 int Reserved;
                                 void *FuncPtr;
                        };
         成员二:     struct __People__myBlcokTest_block_desc_0* Desc;//__People__myBlcokTest_block_desc_0结构体

                            static struct __People__myBlcokTest_block_desc_0 {
                                  size_t reserved;// 升级版本所需要的区域
                                   size_t Block_size;//block大小
                             } 



      构造函数:
              构造函数中成员的处理 在后面 构造函数中参数的处理部分解释;
    __People__myBlcokTest_block_impl_0(void *fp, struct __People__myBlcokTest_block_desc_0 *desc, int flags=0)
    {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
    }
    };

    通过结构体的构造函数生成一个block实例

     __People__myBlcokTest_block_impl_0 blk = __People__myBlcokTest_block_impl_0( __People__myBlcokTest_block_func_0,
    &__People__myBlcokTest_block_desc_0_DATA));

     构造函数参数的意义:
    参数一:    __People__myBlcokTest_block_func_0  //函数实现地址  在把函数赋值给函数指针的时候可以省略&;
    在构造函数参数的意义: 把函数的地址赋值给指针 void *fp
    函数的具体实现代码:
    static void __People__myBlcokTest_block_func_0(struct __People__myBlcokTest_block_impl_0 *__cself) {
            printf("woshinidexiaodaye");
        }
    这里面的__cself是什么后面会解释;
    参数二: &__People__myBlcokTest_block_desc_0_DATA // __People__myBlcokTest_block_desc_0的默认初始化
    { 0, sizeof(struct __People__myBlcokTest_block_impl_0) //使用__People__myBlcokTest_block_impl_0的大小进行初始化

    具体代码:
    static struct __People__myBlcokTest_block_desc_0 { size_t reserved;// 升级版本所需要的区域 size_t Block_size;//block大小 } __People__myBlcokTest_block_desc_0_DATA = { 0, sizeof(struct __People__myBlcokTest_block_impl_0)};

     函数指针 与指针函数点击这里

    构造函数中参数的处理

     __People__myBlcokTest_block_impl_0(void *fp, struct __People__myBlcokTest_block_desc_0 *desc, int flags=0)
               { 
                    impl.isa = &_NSConcreteStackBlock;
                    impl.Flags = flags;
                    impl.FuncPtr = fp;
                    Desc = desc;
                } 
    赋值之后:
    __People__myBlcokTest_block_impl_0(void *fp, struct __People__myBlcokTest_block_desc_0 *desc, int flags=0)
               { 
                    impl.isa = &_NSConcreteStackBlock;//_NSConcreteStackBlock用于初始化isa成员  后面具体解释
                    impl.Flags = 0;
                    impl.FuncPtr =__People__myBlcokTest_block_func_0;
    imlp.Reserved=0;
                    Desc =__People__myBlcokTest_block_desc_0_DATA;
                }

      再来看看block的调用:  

         blk();

    ((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk);
    

     简化

     ((__block_impl *)blk)->FuncPtr)((__block_impl *)blk); =>(blk ->FuncPtr)(blk)
    

     获取blk结构体中函数指针FuncPtr 通过该函数指针调用函数 并且参数值为blk   点击这里

    这个等价于

    (blk ->FuncPtr)(blk) 相当于

       blk -> __People__myBlcokTest_block_func_0(blk);

    再看看

    static void __People__myBlcokTest_block_func_0(struct __People__myBlcokTest_block_impl_0 *__cself) {
            printf("woshinidexiaodaye");
        }

    说明 __cself 就是blk 本身

  • 相关阅读:
    所谓的底层问题
    字符流与字节流
    字节和字符,对信息进行编码
    Asp.net和数据库的一些概念
    谈.NET,由编译器开始谈起
    Extjs中的dom,Ext.Element和Ext.Component对象的关系
    WCF和Delphi通信时序列化的问题
    认真的考虑了下领域模型,发现设计是最难的部分。书上的例子各个对象职责划分的不错,可惜能看懂不代表能设计出。
    MS100 [011020]
    MS100[001]
  • 原文地址:https://www.cnblogs.com/xiaowuqing/p/7648139.html
Copyright © 2020-2023  润新知