## Object Destruction

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. This split is necessary to handle potential cycles due to the nature of the reference counting mechanism used by GObject, as well as dealing with temporary vivification of instances in case of signal emission during the destruction sequence.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    struct _MamanBarPrivate
    {
      GObject *an_object;

      gchar *a_string;
    };

    G_DEFINE_TYPE_WITH_PRIVATE (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 by setting the member
       * NULL; g_clear_object() does this for us.
       */
      g_clear_object (&self->priv->an_object);

      /* Always chain up to the parent class; there is no need to check if
       * the parent class implements the dispose() virtual function: it is
       * always guaranteed to do so
       */
      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);

      /* Always chain up to the parent class; as with dispose(), finalize()
       * is guaranteed to exist on the parent's class virtual function table
       */
      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;
    }

    static void
    maman_bar_init (MamanBar *self);
    {
      self->priv = maman_bar_get_instance_private (self);

      self->priv->an_object = g_object_new (MAMAN_TYPE_BAZ, NULL);
      self->priv->a_string = g_strdup ("Maman");
    }

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, by having a disposed instance revert to an inhert state.