6/05/2011

GObject 入門 (Part 2) - 物件之生命週期

在GObject system若要型別的註冊主要是透過g_type_register_static()完成。若能理解如何使用g_type_register_static(),GObject system的使用方式可說了解絕大部分。
觀察g_type_register_static()的原型(prototype)可以發現,本函數涉入的主要參數為const GTypeInfo *info
GTypeInfo的宣告如下:
struct _GTypeInfo
{
  /* interface types, classed types, instantiated types */
  guint16                class_size;
  
  GBaseInitFunc          base_init;
  GBaseFinalizeFunc      base_finalize;
  
  /* interface types, classed types, instantiated types */
  GClassInitFunc         class_init;
  GClassFinalizeFunc     class_finalize;
  gconstpointer          class_data;
  
  /* instantiated types */
  guint16                instance_size;
  guint16                n_preallocs;
  GInstanceInitFunc      instance_init;
  
  /* value handling */
  const GTypeValueTable *value_table;
};
GTypeInfo資料結構涉及了多個callback functions,可謂環環相扣。總的來說,在型別註冊至GObject system後,系統將透過這些callback functions來管理類別及物件的生命週期。在GObject system架構下,物件自產生至銷毀其流程大致可分為幾個步驟:
Figure#1 Life cycle of a object
於每個型別初次創建之時,GObject system會循著類別樹遞迴呼叫GBaseInitFunc;GClassInitFunc則於各個型別資料(metadata)建立時,被呼叫一次。在實務上會應用到GBaseInitFunc的機會較少,多數情形下於註冊型別時可選擇不提供此callback function。 相較之下,GClassInitFunc顯得重要許多,因為子類別若有必要覆寫(override)父類別的函式,則需要在此時指派(assign)指標。
GBaseFinalizeFunc、GClassFinalizeFunc則分別與GBaseInitFunc、GClassInitFunc對應,在類別創建各階段若有動態配置資源者,必須於相應的解構(destruction)周期中釋放該資源。

Figure#2 Callback functions involved in the life cycle of a object

為了驗證,我們可以利用上一篇宣告的Shape類別加以驗證。
#include <glib.h>

#include "shape.h"

int main(int argc, char** argv)
{
 Shape* shape1;
 Shape* shape2;

 g_type_init();

 shape1 = g_object_new(SHAPE_TYPE, NULL);
 g_print("shape1(0x%08x) is created.\n", (guint)shape1);
 g_object_unref(shape1);

 shape2 = g_object_new(SHAPE_TYPE, NULL);
 g_print("shape2(0x%08x) is created.\n", (guint)shape2);
 g_object_unref(shape2);

 return 0;
}
編譯後,執行的結果:



至於GInstanceInitFunc()則可視為物件的預設建構子(default constructor),當系統分配到屬於該物件的記憶體區塊時此函式將被呼叫,使該物件有機會被指派預設值。若該類別有提供額外建構子(constructor),且於g_object_new()呼叫時有提供相關的參數值,則建構子將於GInstanceInitFunc()完成後執行。官方文件上對此機制的說明如下:
Finally, at one point or another, g_object_constructor is invoked by the last constructor in the chain. This function allocates the object's instance' buffer through g_type_create_instance which means that the instance_init function is invoked at this point if one was registered. After instance_init returns, the object is fully initialized and should be ready to answer any user-request. When g_type_create_instance returns,g_object_constructor sets the construction properties (i.e. the properties which were given tog_object_new) and returns to the user's constructor which is then allowed to do useful instance initialization...
官方文件上的文字描述實在令人有點霧裡看花的感覺,但是實際上的概念並不複雜,之後將有完整範例展示。

No comments:

Post a Comment