Block
1、介绍
Block是将函数及其执行上下文封装起来的对象
2、代码编译
clang -rewrite-objc -fobjc-arc JMBlock.m
- 源码
- 编译后
JMBlock__method_block_impl_0
JMBlockmethod_block_func_0:blcok内部具体实现部分
- 调用
3、截获变量
-
局部变量:
基本数据类型:截获其值
静态变量:截获其指针
对象类型:连同所有权修饰符一起截获
-
不截获全局变量、静态全局变量
编译
clang -rewrite-objc -fobjc-arc JMBlock.m
编译前
编译后
-
方法实现
4、__block修饰符
一般情况下,对被截获变量进行赋值操作需要添加__block修饰符(赋值 != 使用 )
-
需要用__block修饰的
局部变量:基本数据类型、对象类型进行赋值
-
不需要__block修饰的
静态局部变量、全局变量、静态全局变量进行赋值
-
问题1:
-
问题2
-
问题3
5、Block的类型
栈上的、堆上的、全局的,三种类型
6、Block的Copy操作
- 栈上Block的销毁
-
堆上面的Block的销毁
在MRC环境下,如果对栈上的Block进行Copy,会在堆上Copy一份,相当于alloc了一个对象,如果没有其他成员变量指向这个block,并且不进行release,那么会造成内存泄漏。
7、__forwarding的作用
如果栈上的block未被copy到堆上,则multiplier.__forwarding->multiplier = 4,是修改的栈上的值
如果栈上的block被copy到堆上,则multiplier.__forwarding->multiplier = 4,是修改的堆上的值使用栈上的block变量的时候,也是会查找堆上的变量值。
8、block的循环引用
属性 != 成员变量 != 全局变量
成员变量_array会被block捕获
- 问题1:
答案
- 问题2
答案:
如果block长时间不调用,循环引用就会一直存在