zoukankan      html  css  js  c++  java
  • 傻瓜学编程之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 本身

  • 相关阅读:
    动态规划____类数字三角形
    动态规划____编辑距离
    123
    pair queue____多源图广搜
    JAVA练习01
    leetcode — binary-tree-maximum-path-sum
    leetcode — best-time-to-buy-and-sell-stock-iii
    leetcode — best-time-to-buy-and-sell-stock-ii
    leetcode — best-time-to-buy-and-sell-stock
    leetcode — triangle
  • 原文地址:https://www.cnblogs.com/xiaowuqing/p/7648139.html
Copyright © 2011-2022 走看看