The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

Каталог документации / Раздел "Программирование, языки" / Оглавление документа

Уничтожение объекта

Опять, часто сложно выяснить какой механизм использовать для обработки процесса уничтожения объекта: когда сделан последний вызов функции g_object_unref, многое происходит как описано в Table 5, “g_object_unref”.

Процессс уничтожения вашего объекта должен быть разбит на две фазы: вы должны отменить и методы распределения и методы финализации класса.

struct _MamanBarPrivate {
  gboolean dispose_has_run;
};

static GObjectClass parent_class = NULL;

static void
bar_dispose (GObject *obj)
{
  MamanBar *self = (MamanBar *)obj;

  if (self->priv->dispose_has_run) {
   /* если распределение уже выполнено, возвращаемся. */
    return;
  }
  /* убеждаемся что распределение не выполняется дважды. */
  object->priv->dispose_has_run = TRUE;

  /* 
   * В распределении, вы должны освободить все типы ссылок из этого объекта
   * которые могут сами содержать ссылки на себя. В основном,
   * самое простое решение освободить ссылки всех членов которыми вы 
   * владеете.
   */

   /* Формируем цепочку до родительского класса */
   G_OBJECT_CLASS (parent_class)->dispose (obj);
}

static void
bar_finalize (GObject *obj)
{
  MamanBar *self = (MamanBar *)obj;

   /* Формируем цепочку до родительского класса */
   G_OBJECT_CLASS (parent_class)->finalize (obj);
}

static void
bar_class_init (BarClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->dispose = bar_dispose;
  gobject_class->finalize = bar_finalize;

  parent_class = g_type_class_peek_parent (klass);
  g_type_class_add_private(klass,sizeof(MamanBarPrivate));
}

static void
maman_bar_init (GTypeInstance   *instance,
                gpointer         g_class)
{
  MamanBar *self = (MamanBar *)instance;
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, BT_TYPE_PATTERN, BtPatternPrivate);
  self->priv->dispose_has_run = FALSE;

}

Добавьте подобный код в ваш GObject, убедитесь что код собирается и выполняется: распределение и финализация должны быть вызваны в течение последнего освобождения ссылки. Возможно что методы объекта могут быть вызваны после выполнения распределения и перед выполнением финализации. GObject не предполагает что это ошибка программы: вы должны изящно обнаружить это и не предупреждая пользователя не допустить краха. Для этого, вам потребуется следующий код в начале каждого объектного метода, чтобы убедиться что объектные данные остаются доступными перед манипулированием ими:

if (self->private->dispose_has_run) {
  /* Распределение было выполнено. Данные больше недоступны. */
  return;
}




Спонсоры:
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2021 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру