返回

揭秘OC底层Block的本质,深入理解Block的实现原理

IOS

Block的本质

在OC中,Block是一种非常重要的特性,它允许将一段代码块作为参数传递给其他函数或方法。这种特性使得代码更加灵活、易于维护和重用。然而,Block的本质是什么?它又是如何实现的呢?

从表面上看,Block就是一个封装了代码块的对象。但是,Block的本质却远不止如此。Block的本质其实是一种结构体,它包含了三个成员变量:

  • __isa:指向Block类型的指针,用于标识Block的类型。
  • __flags:Block的标志位,用于指示Block的各种属性。
  • __reserved:保留字段,用于扩展Block的功能。

除了这三个成员变量之外,Block还包含了一个指向代码块的指针,该指针指向Block中要执行的代码块。

__Block_byref_age_0类型指针

在Block的结构体中,有一个名为__Block_byref_age_0的类型指针。这个指针指向一个结构体,该结构体包含了两个成员变量:

  • __isa:指向__Block_byref_age_0类型的指针,用于标识结构体的类型。
  • __forwarding:指向Block中要执行的代码块的指针。

__Block_byref_age_0类型的指针的作用是将Block中的代码块与Block的结构体连接起来。当Block被调用时,__Block_byref_age_0类型的指针会将Block中的代码块转发给Block的结构体,从而执行Block中的代码块。

forwarding

forwarding是__Block_byref_age_0结构体中的一个成员变量。它指向Block中要执行的代码块的指针。当Block被调用时,forwarding会将Block中的代码块转发给Block的结构体,从而执行Block中的代码块。

forwarding的本质是一个指向Block中要执行的代码块的指针。但是,forwarding的存储方式却与普通的指针不同。forwarding并不直接存储Block中要执行的代码块的地址,而是存储了Block中要执行的代码块的地址的偏移量。

Block的弊端

Block虽然有很多优点,但它也有一个弊端,那就是不调用就会发生内存泄露的问题。

当Block被创建时,就会在堆上分配一块内存空间来存储Block的数据。如果Block没有被调用,那么这块内存空间就不会被释放,从而导致内存泄露。

为了避免内存泄露,开发者需要在使用完Block之后及时释放Block所占用的内存空间。

总结

Block是一种非常重要的特性,它允许将一段代码块作为参数传递给其他函数或方法。这种特性使得代码更加灵活、易于维护和重用。然而,Block的本质却远不止如此。Block的本质其实是一种结构体,它包含了三个成员变量:__isa、__flags和__reserved。除了这三个成员变量之外,Block还包含了一个指向代码块的指针,该指针指向Block中要执行的代码块。

Block的实现原理也很复杂。在Block的结构体中,有一个名为__Block_byref_age_0的类型指针。这个指针指向一个结构体,该结构体包含了两个成员变量:__isa和__forwarding。__Block_byref_age_0类型的指针的作用是将Block中的代码块与Block的结构体连接起来。当Block被调用时,__Block_byref_age_0类型的指针会将Block中的代码块转发给Block的结构体,从而执行Block中的代码块。

Block虽然有很多优点,但它也有一个弊端,那就是不调用就会发生内存泄露的问题。为了避免内存泄露,开发者需要在使用完Block之后及时释放Block所占用的内存空间。