美文网首页
Block底层实现原理

Block底层实现原理

作者: HotRay | 来源:发表于2017-10-28 13:50 被阅读0次

    Block是带有自动变量值的匿名函数,这个大家都知道。那他底层是怎么实现的呢,他是怎么做到的呢 

    1.首先来看C代码,函数指针!

    float a=1,b=2, c;
    float (*p)(float x, float y);
    p=max;
    c=(*p)(a,b);
    printf("\nmax=%f",c);

    /*等效于 max(a,b)*/ printf("\nmax=%f",c);

    p=min;

    c=(*p)(a,b); /*等效于min(a,b)*/ printf("\nmin=%f",c);

    printf("\nmin=%f",c);

    /*

    ##这样是没有意义的

    */

    void (*t)();

    t= test;

    funcss(1, t);

    /*类似Block 的使用*/

    int (*sum)(int a,int b);

    sum = testsum;

    int v =  sum (10,20);

    NSLog(@"%d",v);

    }

    int  testsum(int a,int b){

    return a+b;

    }

    void test(){

    printf("进来了");

    }

    void funcss (int a ,void* funcname){

    }

    float max(float x,float y){

    printf("Max come hers");

    return x>y?x:y;

    }

    float min(float x,float y){

    printf("Min come hers");

    return x

    }

    上面C函数 只是告诉读者,往本质上去想问题。

    下面我在 程序入口写了一个block 

    int main() {

    void (^blk)(void) = ^{

    printf("block\n");

    };

    blk();

    return 1;

    }

    /*大家都是OC底层是C写的,都是动态调用的,在每个对象实例化,其实都是在发alloc init消息。//Runtime objc_megSend (objc_getClass),Sel_registerName(alloc)

    1.C的函数就是把他结构体的指针传递放进去,然后进行赋值处理。

    */

    ***C 转化与OC C++转化方法 类的实例化方法函数,

    void Myclass::Method(int  age){

    printf ("%p %d\n",this,ahe );;

    }

    //转化C

    void C++InputC (Myclass *this ,int  age ){

    printf ("%p %d\n",this,ahe );;

    }

    //C++调用,

    Method(10);

    //C调用

    struct Myclass cls;

    C++InputC(&cls,10);

    //OC 转化 C

    void OCInputC (struct MyObject *self,SEL _sel,int  age);

    通过Clang 编译C ++文件,入口

    int main() {

    //调用函数

    void (*blk)(void) =

    ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));

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

    //这样写

    struct __main_block_desc_0 tmp =

    ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));//block 语法就是这样的

    // 结构体 =  结构体 (函数,开辟空间)block 语法就是这样的 ,就想alloc init 一样!

    //赋值

    struct __main_block_desc_0 *blk = &tmp ;

    /*1.这句的意思就是 把源代码__main_blockdesc_0 结构体在生成的结构体实力的指针赋值给__main_block_desc_0

    2.相当于

    void (^blk)(void) = ^{

    printf("block\n");

    };

    将block语法生成的block赋值类型变量blk。他等同于将 __main_blockdesc_0结构体实力的指针赋值给变量blk.改源码中的block就是__main_blockdesc_0结构体类型的自动变量,在栈上生成的__main_blockdesc_0结构体的实力

    */

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

    //这样写

    (*blk->impl.FuncPtr)(blk);

    //结构体指针 ,指向结构体指针

    //blk 是一个函数指针可以指向函数地址,指向impl结构体地址,变量 funcptr就是一个__main_block_func_0就是打印函数

    /*

    //这就是简单地使用函数指针调用函数,

    正如我们刚才所确认的,由block语法转化的__main_block_func_0函数的指针被赋值的成员变量funcptr中,另外也说明了,__main_block_func_0 函数的擦拭是指向block值的。在调用该函数的源码中可以看出block是作为参数传递的。

    */

    return 1;

    }

    **结构体定义

    struct __main_block_impl_0 {

    struct __block_impl impl;//结构体变量

    struct __main_block_desc_0* Desc;//Desc指针

    //结构体构造函数,类似void OCInputC (struct MyObject *self,SEL _sel,int  age);

    __main_block_impl_0(void *fp,//数由block语法转化的c御寒函数指针。

    struct __main_block_desc_0 *desc//__main_block_desc_0 实例化后的指针

    , int flags=0) {

    impl.isa = &_NSConcreteStackBlock;//用于初始化结构体的Isa成员的

    impl.Flags = flags;

    impl.FuncPtr = fp;

    Desc = desc; = &__main_block_desc_0_DATA

    }

    //结构体解析

    void *isa;  =&_NSConcreteStackBlock

    int Flags; = = 0

    int Reserved; = 0

    void *FuncPtr;  =__main_block_func_0

    Desc = desc; = &__main_block_desc_0_DATA

    };

    struct __block_impl {

    void *isa;  =&_NSConcreteStackBlock

    int Flags; = = 0

    int Reserved; = 0

    void *FuncPtr;  =__main_block_func_0

    };

    //__maninBlock 结构体变量

    static struct __main_block_desc_0 {

    size_t reserved;

    size_t Block_size;

    }

    //实例化代码 ,开辟空间size_t大小

    __main_block_desc_0_DATA = {

    0, sizeof(struct __main_block_impl_0)

    };

    static void __main_block_func_0(struct __main_block_impl_0 *__cself) {

    printf("block\n");

    }

    相关文章

      网友评论

          本文标题:Block底层实现原理

          本文链接:https://www.haomeiwen.com/subject/bafspxtx.html