воскресенье, 31 августа 2008 г.

Слабые ссылки в GObject (Weak Refs)

В С++ есть различного рода умные указатели и прочие приблуды для упрощения управления динамической памятью, и вот система типов GObject написанная на чистом Си также использует подсчёт ссылок для объектов унаследованных от GObject.

Делается это функциями g_object_ref и g_object_unref, с которыми всё ясно, ref увеличивает счётчик на 1 а unref уменьшает на 1, объект создаётся с счётчиком равным единице. Как только счётчик достигает 0, объект удаляется.

Однако совсем не всегда нужно, чтобы объекты висели в памяти пока кто-нибудь не удосужится их удалить отовсюду. Для этого в GObject есть удобный механизм слабых ссылок. Работает всё очень просто, к объекту можно присоеденить обратные вызовы, которые будут вызваны при удалении объекта. Функция g_object_weak_ref добавляет такой обратный вызов :
void g_object_weak_ref(GObject *object,
GWeakNotify notify,
gpointer data);
Функция g_object_weak_unref удаляет заданный обратный вызов.
void g_object_weak_unref(GObject *object,
GWeakNotify notify,
                         gpointer data);
В таком обратном вызове можно, например, обнулить указтель на удаляемый объект, чтобы потом можно было работать дальше, как будто объект просто не установлен. Код есстественно должен корректоно обрабатывать нулевой указатель. Хотя этим не ограничивается и можно сделать в этом вызове что угодно, память освободить для временных данных, например, или чего ещё, хоть вывести сообщение на экран, мол, такой-то объект удалён.

Так как обнуление указателя вероятно наиболее частный случай использования слабых ссылок, то для этого даже есть специальные функции.
void g_object_add_weak_pointer(GObject *object, gpointer weak_pointer_location);
void g_object_remove_weak_pointer(GObject *object, gpointer weak_pointer_location);
Эти функции соответсвенно добавляют и удаляют специальные вызовы для обнуления укателей по переданному в качестве аргумента адресу.

Я довольно часто использую эти функции, и они действительно облегчают слежение за где-то там выделенной памятью, вопрос где и когда её освободить не стоит.

P.S. Система типов GObject имеет кучу разной вкуснатищи, о которой я буду тут переодически писать.

Комментариев нет: