1
votes

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;
doBlockStuff(^{
   ++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.

1
Your question is quite confusing (not your fault) in that Object was the root class of the Objective-C environ used by the AppKit prior to NSObject. In effect, you need to do NSObject like automatic retain/release as the block is copied/released?bbum
I am not using objective-c. I am using C. The issue is that I need to have a callback for when the block is released.Maz
Right -- assuming you are using the latest versions of llvm 2.x the support for C++ with Blocks is vastly improved. You might be able to use a copy constructor and corresponding destructor to do what you need. Maybe (I haven't explored that stuff enough to say definitively).bbum

1 Answers

0
votes

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);