类型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在内存的布局

程序区:代码段,用来存放代码
数据区:全局变量
堆:我们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跟代理很像
类对象是放在 数据段的
网友评论