1、block的本质
1、block本质上也是一个OC对象,它内部也有个isa指针。
2、block是封装了函数调用以及函数调用环境的OC对象
![](https://img.haomeiwen.com/i1097226/4de0f88895f8a104.png)
![](https://img.haomeiwen.com/i1097226/fe1a95fb089a36cf.png)
![](https://img.haomeiwen.com/i1097226/ffdd10a23335c083.png)
3、auto变量的捕捉(auto 自动变量,离开作用域就销毁)
![](https://img.haomeiwen.com/i1097226/02a9502b98bb4c6e.png)
4、block的变量捕获(capture)
![](https://img.haomeiwen.com/i1097226/df0d16730de0cc93.png)
注:局部变量为啥需要捕获到block内部,因为他需要跨函数进行操作,全局变量不需要,可以任意操作
self是参数,也就是局部变量 可以捕获到block内部。默认传递2个参数(MJPerson *self, SEL _cmd)
OC里面的方法前面2个参数都是方法调用者跟方法名
2、Block的类型
1、block有3种类型,可以通过调用class方法或isa指针查看具体类型,最终类型都是继承自 NSBlock类型
![](https://img.haomeiwen.com/i1097226/676b9612d0ed60c7.png)
![](https://img.haomeiwen.com/i1097226/11c2206921ab0488.png)
堆:动态分配内存,需要程序员申请内存,也需要程序员管理内存
栈:放一些局部变量,系统会自动分配内存,也会自动销毁内存
![]()
-
GlobalBlock:
GlobalBlock
-
StackBlock:
StackBlock
为啥打印不是StackBlock 而是MallocBlock,是因为是ARC环境下
在ARC环境下,编译器会根据情况自动将栈上的block复制到堆上
1.block作为函数返回值(Masonry框架运用大量这种)
2.将block赋值给__strong指针时
3.block作为Cocoa API中方法名含有usingBlock的方法参数时
4.block作为GCD API的方法参数时
三、对象类型的auto变量
![](https://img.haomeiwen.com/i1097226/bb6c6514db625436.png)
四、__block修饰符
![](https://img.haomeiwen.com/i1097226/8def3884d13f5158.png)
五、__block的内存管理
![](https://img.haomeiwen.com/i1097226/9168bafb24f10052.png)
![](https://img.haomeiwen.com/i1097226/98a62206766a2229.png)
六、对象类型的auto变量、__block变量
![](https://img.haomeiwen.com/i1097226/62d2626130625c8e.png)
七、__block的__forwarding指针
![](https://img.haomeiwen.com/i1097226/295070cc0beb58ce.png)
八、被__block修饰的对象类型
![](https://img.haomeiwen.com/i1097226/1f2d060200d7ee9f.png)
九、循环引用
![](https://img.haomeiwen.com/i1097226/cf4f354f1f7c8037.png)
![](https://img.haomeiwen.com/i1097226/c71bb47362abc97b.png)
十、解决循环引用---ARC环境下
// __weak:不会产生强引用,指向的对象销毁时,会自动让指针置为nil
// __unsafe_unretained:不会产生强引用,不安全,指向对象销毁时,指针存储的地址值不变
![](https://img.haomeiwen.com/i1097226/654d98786384fabb.png)
十一、解决循环引用---MRC环境下
MRC下不支持__weak的
![](https://img.haomeiwen.com/i1097226/4647d83017796630.png)
网友评论