OC对象 - Block的类型

OC对象 - Block的类型

1. Block有三种类型

  • 全局: __NSGlobalBlock__( _NSConcreteGlobalBlock )
  • 栈区:__NSStackBlock__ ( _NSConcreteStackBlock )
  • 堆区:__NSMallocBlock__ ( _NSConcreteMallocBlock )

1.1 它们最终都是继承自NSBlockNSBlock则是继承自NSObject

1.2 它们位于程序的不同内存区域

  • NSGlobalBlock: 如果 Block 不访问任何 auto 变量,即它只访问全局变量或静态变量,那么该 Block 将被分配在全局数据区,并且称为全局 Block。全局 Block 的生命周期与应用程序的生命周期相同,因此可以在任何时候使用。

  • NSStackBloc: 如果 Block 访问的变量是在其定义范围内且为 auto 变量(即局部变量),那么该 Block 将被分配在栈上,并且称为栈上 Block。因为栈上 Block 的生命周期受到限制,一旦超出其定义范围,Block 就会失效。这种类型的 Block 通常是在方法内部创建,并且不需要被传递到外部使用。

  • NSMallocBlock: 当一个栈上 Block 被复制(通过调用 copy 方法)并且需要在其定义范围之外继续使用时,该 Block 将被复制到堆上,并且称为堆上 Block。堆上 Block 的生命周期由它的引用计数管理,可以在定义范围之外安全地使用,并且可以在多个地方共享。

2. 不同类型的Block

2.1 特点

block类型环境
NSGlobalBlock没有访问auto变量
NSStackBlock访问了auto变量
NSMallocBlock__NSStackBlock__调用了copy

2.2 每一种类型的block调用copy之后

3 验证

3.1 打印black类型


我们逐级打印blackclasssuperclass,可以看到最终是继承自NSBlockNSBlock则是继承自NSObject

3.1 验证不同类型的Block

我们已经知道,访问了auto变量的block是NSStackBlock类型,__NSStackBlock__调用了copy后是NSMallocBlock

当运行如下代码,却发现访问了 auto 变量的 block 却是__NSMallocBlock__

3.2 ARC和MRC

这是因为,现在项目默认是启用ARC的,ARC下会自动帮我们添加copy操作(具体规则后面章节讲),我们先把项目设置为MRC


重新运行

和我们预期的一样

4. block的copy

4.1 在ARC环境下,编译器会根据情况自动将栈上的block复制到堆上,比如以下情况

  • block作为函数返回值时
  • 将block赋值给__strong指针时
  • block作为Cocoa API中方法名含有usingBlock的方法参数时
  • block作为GCD API的方法参数时
4.1.1 block作为函数返回值时

通过下面示例,验证了block作为函数返回值时是__NSMallocBlock__,直接创建打印则是__NSStackBlock__

4.1.2 将block赋值给__strong指针时
  • 创建ZSXPerson类,并声明一个strong修饰的block属性
@interface ZSXPerson : NSObject

@property (strong, nonatomic) void (^block)(void);

@end
  • 初始化ZSXPerson实例对象person,并把block赋值给person.block


此时的 block 是__NSMallocBlock__

4.1.3 block作为Cocoa API中方法名含有usingBlock的方法参数时

示例:

4.1.4 block作为GCD API的方法参数时

示例:

4.2 MRC下block属性的建议写法

@property (copy, nonatomic) void (^block)(void);

4.3 ARC下block属性的建议写法

@property (strong, nonatomic) void (^block)(void);
@property (copy, nonatomic) void (^block)(void);

@oubijiexi

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值