通过block有哪些对象类型这篇文章,我们知道了不同类型的block调用copy后的结果如下图所示:
一、哪些情况block自动copy到堆上?
在ARC环境下,编译器会根据情况自动将栈上的block复制到堆上,比如以下情况
1、block作为函数返回值时。
2、将block赋值给__strong指针时。
3、block作为Cocoa API中方法名含有usingBlock的方法参数时。
4、block作为GCD API的方法参数时。
MRC下block属性的建议写法
@property (copy, nonatomic) void (^block)(void);
ARC下block属性的建议写法
@property (strong, nonatomic) void (^block)(void); @property (copy, nonatomic) void (^block)(void);
为了统一写法,建议都是用 copy 修饰:
@property (copy, nonatomic) void (^block)(void);
二、堆栈上的block对auto变量的引用是什么关系?
2.1、block是在栈上
不会对auto变量产生强引用。
因为block本身随时会被销毁,所以对auto变量强引用没有什么意义。
2.2、block被拷贝到堆上
– > 会调用block内部的 copy 函数
------ > copy 函数内部会调用_Block_object_assign函数
--------------> _Block_object_assign 函数会根据 auto 变量的修饰符(__weak,__strong,__unsafe_unretained)做出相应的操作,类似于retain(形成强引用、若引用)。
2.3、block从堆中删除
– > 会调用block内部的 dispose 函数
------ > dispose函数内部会调用 _Block_object_dispose 函数
--------------> _Block_object_dispose 函数会自动释放引用的auto变量,类似于release.
注意:
__weak 弱引用需要运行时支持,需要增加运行时编译:
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-runtime=ios-8.0.0 main.m