iOS-Block总结

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循环引用无法释放内存,造成内存泄露。

你可能感兴趣的:(iOS-Block总结)