iOS之获取Block retain的objects
Block管理Objective-C
对象实例的原理
Block
的实现结构体见如下图所示,Block
对于捕获的Objective-C
对象实例,会在Block
实现的结构体中创建一个变量指向Objective-C
对象实例,当Block
将要释放时,会调用dispose_helper
函数,该函数会调用所有需要进行内存管理的所捕获的对象,如Block
、__block
变量、__attribute__((NSObject))
变量或有constructor/destructor
的C++
const
对象。
获取Block retain的Objective-C对象实例
所以,怎么能够拿到retain
的Objective-C
对象实例呢,方法为创建fake
对象,来模拟捕获的Objective-C
对象实例,然后我们程序来调用Block
的dispose_helper
方法(dispose_helper
方法接收一个参数,值为Block
的指针),该方法会调用对象实例的release
方法,我们只需要在fake
对象中实现release
方法,如果release
方法被调用,所以该fake
对象对应的真实变量为Objective-C
对象实例。
那么需要创建多少个fake
对象呢,首先,Objective-C
对象实例在Block
的struct
中的位置是指针对齐的,所以我们可以获取Block
结构体的大小,除以指针的大小取上即为需要创建的fake
对象的数量,Block
结构体的size
可以通过block->descriptor->size
来获取。
得到需要创建fake
对象的数量count
后,创建一个数组,再创建count
个fake
对象,将数组指针传入dispose_helper
即可。对于调用了release
方法的对象,记录其索引值,通过访问block[index]
即可拿到真正的Objective-C
对象实例。
注意
如上所说的捕获的Objective-C
对象实例,不包括使用__block
创建的实例,因为使用__block
创建的变量,会加一层间接层,并不会在Block
结构体中创建指向实例对象的变量,而是指向另一个间接层结构体。