1、block的特点:
block是C语言;
block是一种数据类型、可以当做参数,也可以用做返回值
block是预先准备好的代码块、在需要的时候调用,(需要好好理解“需要时”);
2、定义block
3、block引用外部变量
在定义block时,如果使用了外部变量,block内部会默认对外部变量做一次copy;
默认情况下,不允许在block内部修改外部变量的值;
在外部变量声明时,使用__block修饰符,则可以在block内部修改外部变量的值;
4、数组的遍历&排序;
遍历:enumerateObjectsUsingBlock:
所有的参数都已经准备到位,可以直接使用
效率比for高,官方推荐使用;
举例:懒加载
enumerateObjectsUsingBlock遍历:
[tempArrayenumerateObjectsUsingBlock:^(id_Nonnullobj,NSUIntegeridx,BOOL*_Nonnullstop) {
NSDictionary*dict = (NSDictionary*)obj;
Heros*hero = [HerosherosWithDict:dict];
[ArrMaddObject:hero];
}];
for—IN遍历:
for(NSDictionary*dictintempArray) {
Heros*heros = [HerosherosWithDict:dict];
[ArrMaddObject:heros];
}
排序:sortedArrayUsingComparator:
5.block在内存中的位置
•Block如果没有引用外部变量
保存在全局区(MRC/ARC一样)
•Block如果引用外部变量
ARC保存在堆区;MRC保存在栈区必须用copy修饰block;
block快的存储位置(block入口的地址)可能存放在3个地方:代码区(全局区)、堆区、栈区(ARC情况下会自动拷贝到堆区、因此ARC下只有两个地方:代码区和堆区)。
•代码区:不访问出去栈区的变量(如局部变量),且不访问堆区的变量(如用alloc创建的对象)时,此时block存放在代码区;
•堆区:如果访问了处于堆区的变量(如局部变量),或堆区的变量(如用alloc创建的对象),此时block存放在堆区
6.block的循环引用
block对于其变量都会形成strong reference,对于self也会形成strong reference,而如果self本身对block也是strong reference的话,就会形成strong reference循环,造成内存泄露。
解决方法:一般在block外面加一句—week typeof(self)weekSelf = self;防止self在block中应用计数加1,导致self和block循环引用无法释放内存,造成内存泄露。