GObject Reference Manual |
---|
Again, it is often difficult to figure out which mechanism to use to
hook into the object's destruction process: when the last
g_object_unref
function call is made, a lot of things happen as described in
Table 5, “g_object_unref”.
The destruction process of your object might be split in two different phases: dispose and the finalize.
#define MAMAN_BAR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MAMAN_TYPE_BAR, MamanBarPrivate)) struct _MamanBarPrivate { GObject *an_object; gchar *a_string; }; G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT); static void maman_bar_dispose (GObject *gobject) { MamanBar *self = MAMAN_BAR (gobject); /* * In dispose, you are supposed to free all types referenced from this * object which might themselves hold a reference to self. Generally, * the most simple solution is to unref all members on which you own a * reference. */ /* dispose might be called multiple times, so we must guard against * calling g_object_unref() on an invalid GObject. */ if (self->priv->an_object) { g_object_unref (self->priv->an_object); self->priv->an_object = NULL; } /* Chain up to the parent class */ G_OBJECT_CLASS (maman_bar_parent_class)->dispose (gobject); } static void maman_bar_finalize (GObject *gobject) { MamanBar *self = MAMAN_BAR (gobject); g_free (self->priv->a_string); /* Chain up to the parent class */ G_OBJECT_CLASS (maman_bar_parent_class)->finalize (gobject); } static void maman_bar_class_init (MamanBarClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->dispose = maman_bar_dispose; gobject_class->finalize = maman_bar_finalize; g_type_class_add_private (klass, sizeof (MamanBarPrivate)); } static void maman_bar_init (MamanBar *self); { self->priv = MAMAN_BAR_GET_PRIVATE (self); self->priv->an_object = g_object_new (MAMAN_TYPE_BAZ, NULL); self->priv->a_string = g_strdup ("Maman"); }
Add similar code to your GObject, make sure the code still builds and runs: dispose and finalize must be called during the last unref.
It is possible that object methods might be invoked after dispose is run and before finalize runs. GObject does not consider this to be a program error: you must gracefully detect this and neither crash nor warn the user.