How to implement custom retain-release for blocks with clang
I have an object system which I wrote in C which contains reference counting for objects (objects are just structs which have a retainCount int). If I have a block like the following:
typedef void (^MyBlock)();
void doBlockStuff(MyBlock b){
Block_copy(b);
//...
}
__block int i=0;
doBlo开发者_如何学运维ckStuff(^{
++i;
});
then the runtime heap-allocates the integer i when Block_copy is called. However, if I use a reference-counted object instead:
typedef void (^MyBlock)();
void doBlockStuff(MyBlock b){
Block_copy(b);
//...
}
__block Object* obj=Object_New();
doBlockStuff(^{
DoObjectStuff(obj);
});
then the pointer itself, not it's referenced value, is heap-allocated by the runtime (although it is already heap-allocated by the Object_New function). Because the object is reference counted, another function could come along and release the object before the block is released. If I explicitly retain the object, then it will never be freed. So, my question is, how do I add a callback to Block_dealloc to explicitly release the object when it is freed?
Thanks.
Wrap your C Object* in a __block storage C++ type. Something like so:
Class:
template<typename T>
class ObjectPtr
{
public:
T* ptr;
public:
ObjectPtr(T* val) : ptr(val)
{
Object_Retain(ptr);
}
virtual ~ObjectPtr()
{
Object_Release(ptr);
}
};
Usage:
struct Object* blah = Object_New();
__block ObjectPtr<Object> obj = ObjectPtr<Object>(blah);
Object_Release(blah);
b = ^void(void){obj.ptr;};
b = Block_copy(b);
// ...
b();
Block_release(b);
精彩评论