Block-类型

2020-10-23  本文已影响0人  越天高

类型01

block有3种类型,可以通过调用class方法或者isa指针查看具体类型,最终都是继承自NSBlock类型
计算block是对象类,那么他就有这么几个特征
1,使用class查看他的具体特征

void (^block)(void)=^{
            NSLog(@"111");

        };
        
        int age = 10;
        void (^block1)(void)=^{
            NSLog(@"%i", age);

        };
        
        NSLog(@"%@-%@-%@", [block class],[block1 class],[^{
            NSLog(@"%i", age);

        } class]);
// __NSGlobalBlock__-__NSMallocBlock__-__NSStackBlock__

但是编译完毕之后,他们最终都变成了isa指向的是以个NSConCreteStackBlock,为什么跟最终的c++不一样 ,我们一切以运行时为准。clang生成的代码,并不一定是我们真正转成的代码,llvm编译器,他会生成一种中间文件。cpp只能用来作为参考

  __NSGlobalBlock__ ( _NSConcreteGlobalBlock )
        __NSStackBlock__ ( _NSConcreteStackBlock )
        __NSMallocBlock__ ( _NSConcreteMallocBlock )

这三种类型的block在内存的布局


block在内存中的布局

程序区:代码段,用来存放代码
数据区:全局变量
堆:我们alloc出来的那些对象,动态分配内存,需要我们自己申请,管理内存
栈:局部变量,系统自己分配,管理内存,

类型02

block是怎么划分类型的

 //__NSGlobalBlock__:没有访问局部auto变量
        //他调用了copy依然还是global
        void (^block)(void)=^{
            NSLog(@"111");

        };
        
        int age = 10;
        //__NSMallocBlock__ :访问局部auto变量(arc),因为ARC帮我们做了很多事情
        //copy只会引用+1;
        //mrc __NSStackBlock__ 放到栈上面之后,会存在问题,因为内存是系统自动管理的,所以有可能我们访问的俄时候变量已经销毁了
        //再去那个地址取值,就有可能是乱值。
        //把它放到堆里面就可以保证他不自动销毁
        //如果__NSStackBlock__执行了copy之后,他就会放到堆上面,就不会被销毁,捕获的值还是刚刚捕获的值
        void (^block1)(void)=^{
            NSLog(@"%i", age);

        };
        
        NSLog(@"%@-%@-%@", [block class],[block1 class],[^{
            NSLog(@"%i", age);

        } class]);

答疑问

function指向的函数房贷代码区
宏不是全局变量,只是替换

通知是一对多,代理一对一,block跟代理很像

类对象是放在 数据段的

上一篇 下一篇

猜你喜欢

热点阅读