OC对象 – Block 的本质

💡 原文中文,约1300字,阅读约需4分钟。
📝

内容提要

OC对象-Block是封装代码的OC目标,底层结构是__block_impl。初始化block时,传入函数和描述信息。调用block时,通过FuncPtr调用函数。

🔎

延伸解读

Block 的底层结构:从 OC 对象到 C++ 结构体

文章指出 Block 的实质是 OC 对象,内部包含 isa 指针,底层结构为 __block_impl。通过将 Block 代码转换为 C++ 代码,可以验证其结构。初始化时生成 __main_block_impl_0 结构体,其中 impl 成员即为 __block_impl,包含 FuncPtr 和 Desc 等字段。这揭示了 Block 并非简单的函数指针,而是封装了函数调用及其环境的对象。

初始化与调用:函数指针与描述信息的传递

初始化 Block 时,传入两个参数:封装了 Block 代码的函数指针 __main_block_func_0 和描述信息 __main_block_desc_0_DATA。前者赋值给 impl.FuncPtr,后者赋值给 Desc。调用 Block 时,通过 block->FuncPtr 找到函数并执行。描述信息中的 Block_size 记录了 Block 的大小,reserved 为保留字段。这一机制说明 Block 的调用本质是间接函数调用。

使用 Block 的潜在风险:循环引用

文章提到 Block 常用于传值和事件传递,但使用不当可能导致循环引用。由于 Block 会捕获其所在环境,若在 Block 内部强引用外部对象,而该对象又持有 Block,就会形成引用环。虽然文章未展开解决方案,但读者应意识到这是 Block 使用中需要警惕的问题,需结合具体场景分析。

❓

Q&A

OC对象-Block的本质是什么?

OC对象-Block是封装代码的OC目标,底层结构是__block_impl。

Block在开发中常用于哪些场景?

Block常用于封装代码、传值和事件传递。

如何初始化一个Block?

初始化Block时,传入函数和描述信息,形成__main_block_impl_0结构体。

调用Block时是如何执行代码的?

调用Block时,通过FuncPtr调用初始化时传入的函数,执行Block中的代码。

使用Block时可能会遇到什么问题?

使用不当可能导致循环引用等问题。

Block的底层结构可以如何验证?

可以通过将Block转成C++代码来验证其底层结构。

➡️

继续阅读