iOS之Block的类型分析

根据Block的存储域,可以分为三类:

1.NSGlobalBlock  全局区(程序的数据区)

2.NSStackBlock  栈区域(只在MRC下存在),超出变量的作用域,栈上的Block和__block类型变量都被销毁.

3.NSMallocBlock 堆区域, 在变量作用域结束时,变量不受影响


那么我们平时创建的Block属于哪一种呢?

总结下,生成在全局区block的情况:

 1.定义全局变量的时候有block语法

  2.block语法的表达式中没有使用截获的自动变量时

其余的block都是栈区Block.那么堆区的Block又是怎么回事呢?

其实,一般在ARC开启的情况下,在栈区创建的Block都会复制到堆区(系统自动进行),以防止超出作用域后block变量会被销毁而不能正常使用.一般,以下几种情况下,栈区的Block会复制到堆区:

1.调用Block的copy实例方法(ARC自动调用),或者Block_copy方法

2.Block作为函数返回值

3.将Block的值赋给__strong修饰的id类型或Block类型成员变量

4.将方法中含有usingBlock的Cocoa框架方法或GCD的API中传递Block时


MRC情况下Block从栈区到堆区的复制:

Block_copy(block体),为了避免内存泄漏, Block_copy必须与Block_release(block)结合使用.

同时, Foundation框架提供了两个与上述函数作用相同的方法:

block = [block体 copy];  [block release] (ARC下的自动复制就是调用了copy方法)


__block:

Block语法表达式中使用的局部变量被作为成员变量追加到Block所在的结构体中,因而不能修改外面的局部变量(基本数据类型);

当局部变量使用__block修饰时,其地址被作为成员变量追加到Block所在的结构体中,因此可以对该局部变量进行修改


你可能感兴趣的:(iOS之Block的类型分析)