Block 03 - 内存管理

Block 03 - 内存管理

Block 的 copy

  • 在 ARC 环境下,编译器会根据情况自动将栈上的 Block 复制到堆上:

    • Block 作为函数返回值时。
    • 将 Block 赋值给 __strong 指针时。
    • Block 作为 Cocoa API 中方法名含有 UsingBlock 的方法参数时。
    • Block 作为 GCD API 的方法参数时。
  • 在 MRC 环境下 Block 属性的建议写法:
    @property(nonatomic, copy) void (^block)(void);

  • 在 ARC 环境下 Block 属性的建议写法:
    @property(nonatomic, strong) void(^block)(void);
    @property(nonatomic, copy) void(^block)(void);

当 Block 内部访问了对象类型的 auto 变量、__block 对象时

  • 当 Block 在栈上时,对它们都不会进行强引用。
  • 当 Block 被拷贝到堆上时:
    • 会调用 Block 内部的 copy 函数。
    • copy 函数内部会调用 _Block_object_assign 函数。
    • _Block_object_assign 函数会对 __block 对象进行强引用。
    • _Block_object_assign 函数会根据 auto 变量的修饰符(__strong, __weak, __unsafe_unretained)做出相应的操作,进行强引用(retain)或弱引用。
  • 当 Block 从堆上移除时:
    • 会调用 Block 内部的 dispose 函数。
    • dispose 函数内部会调用 _Block_object_dispose 函数。
    • _Block_object_dispose 函数会自动释放被强引用的对象(release)。
_Block_object_assign((void*)&dst->o, (void*)src->o, 3/*BLOCK_FIELD_IS_OBJECT*/);
_Block_object_assign((void*)&dst->b, (void*)src->b, 8/*BLOCK_FIELD_IS_BYREF*/);

_Block_object_dispose((void*)src->o, 3/*BLOCK_FIELD_IS_OBJECT*/);
_Block_object_dispose((void*)src->b, 8/*BLOCK_FIELD_IS_BYREF*/);

代码中如果使用了 __weak,在使用 clang 将 Objective-C 转换为 C++ 时,会有以下问题:
cannot create __weak reference in file using manual reference

解决方式(在命令中指定支持 ARC、运行时系统版本):
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc ==-fobjc-arc== ==-fobjc-runtime=ios-8.0.0== class.m -o class.cpp

__block 对象的内存管理

  • 当 __block 对象在栈上时,不会对被包装的变量指向的对象进行强引用。
  • 当 __block 对象被拷贝到堆上时:
    • 会调用 __block 对象内部的 __Block_byref_id_object_copy 函数。
    • __Block_byref_id_object_copy 函数内部会调用 _Block_object_assign 函数。
    • _Block_object_assign 函数会根据变量的修饰符(__strong、__weak、__unsafe_unretained)做出相应的操作,进行强引用(retain,仅限于 ARC 环境)或弱引用。
  • 当 __block 对象从堆上移除时:
    • 会调用 __block 变量内部的 __Block_byref_id_object_dispose 函数。
    • __Block_byref_id_object_dispose 函数内部会调用 _Block_object_dispose 函数。
    • _Block_object_dispose 函数会自动释放被强引用的对象(release)。
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Blocks Blocks Blocks 是带有局部变量的匿名函数 截取自动变量值 int main(){ ...
    南京小伙阅读 4,558评论 1 3
  • 1. Block内存管理 OC代码转换成C++代码 _block的内部要调用外边的变量,_block的desc0的...
    周灬阅读 3,607评论 0 1
  • 一、Block的底层结构及本质 (1)block本质: 从代码可以看出,Block的本质就是NSObject. 也...
    王的for阅读 3,823评论 0 2
  • Block的底层基本结构 通过clang命令查看编译器是如何实现Block的,在终端输入clang -rewrit...
    小凉介阅读 20,379评论 22 96
  • 再没有什么 比撕扯一张白纸简单 任由笔肆意挥霍 大不了大手一挥 一切又重头开始 再没有什么 比撕扯一张白纸简单 空...
    居弆阅读 2,405评论 2 3

友情链接更多精彩内容