The OpenNET Project
 
Поиск (ключи):    ПРОГРАММЫ СТАТЬИ СОВЕТЫ ФОРУМ
  WIKI НОВОСТИ (+) MAN'ы ДОКУМЕНТАЦИЯ

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

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

Опять, часто сложно выяснить какой механизм использовать для обработки процесса уничтожения объекта: когда сделан последний вызов функции 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;
}


ПОДПИШИСЬ НА ЖУРНАЛ Linux Format 2012!

Журнал "Linux Format" (Линукс Формат)- Единственный в России и странах СНГ журнал на русском языке, посвящённый Linux и свободному ПО. Журнал для IT-директоров, IT-менеджеров, программистов, системных администраторов, учителей школ и преподавателей ВУЗов и всех пользователей ПК. В каждом выпуске: Новости индустрии OpenSource, обзоры новинок свободного ПО, обучающие и методические статьи.

Каждый, кто оформит подписку, получает бонусы и подарки- объёмные наклейки на системный блок, диск с архивом номеров за 2005-2011 г.г. и ежемесячно электронную версию журнала в pdf-формате.

Оформить подписку на год


  Закладки на сайте
  Проследить за страницей
Created 1996-2012 by Maxim Chirkov  
ДобавитьРекламаВебмастеруГИД  
RUNNet TopList