定义
带有局部变量的匿名函数。
标志
^
使用
跟函数很像:
1、可以保存代码;
2、可以有返回值;
3、可以有形参;
4、调用方式一样;
存储区域
三种存储方式:栈、全局、堆。
优点
帮助组织独立的代码段,提高代码的复用性和可读性。
实现机制
方法回调。
(所谓回调,是在某个事件发生前预先准备好的一段代码,相应的事件一旦发生,系统就会执行这段代码。)
特性
捕获变量。
概念
当某个block对象访问了一个在该block对象之前声明的变量时,可以称该block对象捕获了这个变量。一旦block对象捕获了某个变量,该变量之后的变化就不会对捕获后的变量产生任何影响。
实质
默认情况下,在block中访问的外部变量是复制过去的,即:写操作不对原变量生效。
原因
Apple这样设计应该是考虑到了block的特殊性,block也属于“函数”的范畴,变量进入block,实际就是已经改变了作用域。在几个作用域之间进行切换时,如果不加上这样的限制,变量的可维护性将大大降低。
如果需要修改外部变量,怎么实现
1、修改变量为static全局变量;
2、用__block关键字修饰变量;
(__block关键字的底层实现原理:__block所起到的作用就是只要观察到该变量被 block 所持有,就将“外部变量”在栈中的内存地址放到了堆中。进而在block内部会直接引用变量的地址,所以也可以修改外部变量的值。)
循环引用问题
block创建前weak化
概念
在 block 内如果需要访问 self 的方法、变量,建议使用 weakSelf。
原因
创建block函数之前一般需要对self进行weak化,否则会造成循环引用无法释放,即内存泄漏。
方法
__weak typeof(self) weakSelf = self;
ARC和MRC两种情况下的weak化:
1. ARC:通过使用__weak声明一个weakself来代替原来的self,已告诉block内部不要对self进行强引用。
2. MRC:解决方式与上述基本一致,只不过将__weak关键字换成__block即可。
block内部需多次访问要strong化
概念
如果在 block 内需要多次访问 self,则需要使用 strongSelf。
原因
保证代码在执行到block中,self不会被释放,当block执行完后,会自动释放该strongSelf。在多线程环境下(block中的weakSelf有可能被析构的情况下),需要先将self转为strong指针,避免在运行到某个关键步骤时self对象被析构。
方法
__strong typeof(weakSelf) strongSelf = weakSelf; //内部strong
经典代码
weak–strong dance
(以下代码来自AFNetworking,堪称使用weak–strong dance的经典)
代码分析
1. __weak __typeof(self)weakSelf = self:
为防止callback内部对self强引用,weak一下。
2.__strong__typeof(weakSelf)strongSelf = weakSelf:
如果不转成strongSelf而使用weakSelf,后面几句话中,有可能在第四句执行之后self的对象可能被析构掉,然后后面的StausBlock没有执行,导致逻辑错误。
3. 使用block前对block判空。
4. typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型。它返回值是一个字符串,该字符串说明运算数的类型。即可以根据typeof()括号里面的变量,自动识别变量类型并返回该类型。