2011-02-08 3 views
1

У меня есть объектная система, которую я написал в C, которая содержит подсчет ссылок для объектов (объекты - это просто структуры, у которых есть keepCount int). Если у меня есть блок, как в следующем:Как реализовать пользовательский удержание-релиз для блоков с clang

typedef void (^MyBlock)(); 

void doBlockStuff(MyBlock b){ 
    Block_copy(b); 
    //... 
} 

__block int i=0; 
doBlockStuff(^{ 
    ++i; 
}); 

среда выполнения кучного выделяет целое число я, когда Block_copy называется. Однако, если я использую эталонный подсчет объект вместо:

typedef void (^MyBlock)(); 

void doBlockStuff(MyBlock b){ 
    Block_copy(b); 
    //... 
} 

__block Object* obj=Object_New(); 
doBlockStuff(^{ 
    DoObjectStuff(obj); 
}); 

затем сам указатель, а не это эталонное значение, является кучным выделено временем выполнения (хотя это уже кучного выделяется функцией Object_New). Поскольку объект подсчитан ссылкой, другая функция может прийти и освободить объект до того, как будет выпущен блок. Если я явно сохраню объект, он никогда не будет освобожден. Итак, мой вопрос: как добавить обратный вызов Block_dealloc для явного освобождения объекта при его освобождении?

Спасибо.

+0

Ваш вопрос довольно запутанным (не ваша вина) в том, что 'Object' был корень класс Objective-C окружа используемый AppKit до 'NSObject'. По сути, вам нужно делать 'NSObject' как автоматическое сохранение/освобождение при копировании/выпуске блока? – bbum

+0

Я не использую объектив-c. Я использую C. Проблема в том, что мне нужно иметь обратный вызов, когда выйдет блок. – Maz

+0

Право - ** если вы используете последние версии llvm 2.x **, поддержка C++ с блоками значительно улучшена. Возможно, вы сможете использовать конструктор копирования и соответствующий деструктор, чтобы делать то, что вам нужно. Может быть (я не исследовал это достаточно, чтобы сказать окончательно). – bbum

ответ

0

Оберните свой объект C * в хранилище C++ типа __block. Что-то вроде этого:

Класс:

template<typename T> 
class ObjectPtr 
{ 
public: 
    T* ptr; 
public: 
    ObjectPtr(T* val) : ptr(val) 
    { 
     Object_Retain(ptr); 
    } 

    virtual ~ObjectPtr() 
    { 
     Object_Release(ptr); 
    } 
}; 

Использование:

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