Как реализовать пользовательский retain-release для блоков с помощью clang - PullRequest
1 голос
/ 09 февраля 2011

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

typedef void (^MyBlock)();

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

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

, то динамическая куча выделяет целое число 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 для явного освобождения объекта при его освобождении?

Спасибо.

1 Ответ

0 голосов
/ 28 февраля 2011

Оберните ваш объект C * в блочное хранилище типа C ++. Примерно так:

Класс:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...