?? sec-finalization.html
字號:
is part of the public API. The <span class="STRUCTNAME"> GtkObject</span> implementation of the <span class= "STRUCTNAME">destroy</span> method is called <tt class= "FUNCTION">gtk_object_real_destroy()</tt>: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static voidgtk_object_real_destroy (GtkObject *object){ if (GTK_OBJECT_CONNECTED (object)) gtk_signal_handlers_destroy (object);} </pre> </td> </tr> </table> <p> This code simply cleans up any signal handlers associated with the object. <tt class="FUNCTION"> gtk_object_real_destroy()</tt> is the default handler invoked when the <span class="SYMBOL">"destroy"</span> signal is emitted. <tt class="FUNCTION"> gtk_object_destroy()</tt> invokes the (possibly overridden) class function <span class="STRUCTNAME">shutdown</span>; the default shutdown method emits the <span class="SYMBOL"> "destroy"</span> signal. </p> <p> Finalization is initiated by <tt class="FUNCTION"> gtk_object_unref()</tt>, if and only if the reference count has reached 0. <tt class="FUNCTION">gtk_object_unref()</tt> can be invoked directly by a user, but often <tt class= "FUNCTION">gtk_object_destroy()</tt> invokes it. Here it is: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> voidgtk_object_unref (GtkObject *object){ g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_OBJECT (object)); g_return_if_fail (object->ref_count > 0); if (object->ref_count == 1) { gtk_object_destroy (object); g_return_if_fail (object->ref_count > 0); } object->ref_count -= 1; if (object->ref_count == 0) { object->klass->finalize (object); }} </pre> </td> </tr> </table> <p> If an object has a reference count of 1, calling <tt class= "FUNCTION">gtk_object_unref()</tt> invokes the shutdown and destroy methods (via <tt class="FUNCTION"> gtk_object_destroy()</tt>) and then finalizes the object (unless the reference count was incremented sometime during the shutdown/destroy process; this is allowed and will prevent finalization). If an object's reference count is greater than 1 at the start of <tt class="FUNCTION"> gtk_object_unref()</tt>, the reference count is simply decremented. </p> <p> Again, notice that an object can be <i class="EMPHASIS"> destroyed</i> while the reference count is greater than 1 if the user calls <tt class="FUNCTION"> gtk_object_destroy()</tt>; if this happens, finalization does not take place until the holders of the remaining references call <tt class="FUNCTION"> gtk_object_unref()</tt>. In the most common case, the <tt class="FUNCTION">gtk_object_destroy()</tt> implementation holds the last reference count --- have another look at the <tt class="FUNCTION">gtk_object_destroy()</tt> code with this in mind. </p> <p> For completeness, here is <span class="STRUCTNAME"> GtkObject</span>'s default <span class="STRUCTNAME"> finalize</span> method: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static voidgtk_object_finalize (GtkObject *object){ gtk_object_notify_weaks (object); g_datalist_clear (&object->object_data); gtk_type_free (GTK_OBJECT_TYPE (object), object);} </pre> </td> </tr> </table> <p> The three function calls in this method do the following: </p> <ul> <li> <p> Invoke "weak references," which are callbacks invoked on object finalization. This is a little-used <span class="STRUCTNAME">GtkObject</span> feature not described in this book (usually connecting to the <span class="SYMBOL">"destroy"</span> signal is more appropriate). </p> </li> <li> <p> Clear any object data (described in <a href= "sec-objectdata.html">the section called <i>Attaching Data to Objects</i></a>). </p> </li> <li> <p> Free the instance struct. </p> </li> </ul> <p> <a href="z57.html#WIDGETLIFECYCLE">the section called <i> Widget Life Cycle</i> in the chapter called <i>GTK+ Basics</i></a> has more to say about reference counting and destruction with respect to widgets. </p> <div class="SECT2"> <h2 class="SECT2"> <a name="SEC-CHAINUP">Chaining Up</a> </h2> <p> If an object overrides the shutdown, destroy, or finalize methods, it should chain up to the default implementation, to ensure that each parent class has a chance to clean up. Here is an example of chaining up: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static voidgtk_widget_real_destroy (GtkObject *object){ /* ... */ if (parent_class->destroy) parent_class->destroy (object);}; </pre> </td> </tr> </table> <p> <tt class="FUNCTION">gtk_widget_real_destroy()</tt> is installed in the widget's class struct in the class initialization function, overwriting the <span class= "STRUCTNAME">GtkObject</span> default. <span class= "STRUCTNAME">parent_class</span> is a pointer to the parent's class struct; usually you will want to store this pointer in your class initialization function, as <span class="STRUCTNAME">GtkWidget</span> does: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> static GtkObjectClass *parent_class = NULL;/* ... code omitted ... */static voidgtk_widget_class_init (GtkWidgetClass *klass){ GtkObjectClass *object_class; object_class = (GtkObjectClass*) klass; parent_class = gtk_type_class (gtk_object_get_type ()); /* ... code omitted ... */ object_class->set_arg = gtk_widget_set_arg; object_class->get_arg = gtk_widget_get_arg; object_class->shutdown = gtk_widget_shutdown; object_class->destroy = gtk_widget_real_destroy; object_class->finalize = gtk_widget_finalize;} </pre> </td> </tr> </table> <p> Of course, if <span class="STRUCTNAME"> parent_class</span> is not a <span class="STRUCTNAME"> GtkObjectClass*</span>, you will need to cast it with the <tt class="FUNCTION">GTK_OBJECT_CLASS()</tt> macro. </p> <p> An aside: notice that you should <i class="EMPHASIS"> not</i> chain up when implementing <span class= "STRUCTNAME">get_arg</span> and <span class="STRUCTNAME"> set_arg</span> --- GTK+ special-cases these methods in <tt class="FUNCTION">gtk_object_set()</tt> and <tt class= "FUNCTION">gtk_object_get()</tt>. Recall that the <span class="STRUCTNAME">GtkObject</span> base class initializer zeroes these two methods, rather than leaving the default implementation. When setting or getting an argument value, GTK+ uses the information provided on argument registration to jump directly to the correct class struct and invoke only the correct <span class= "STRUCTNAME">get_arg</span> or <span class="STRUCTNAME"> set_arg</span> method. Chaining up would be a much slower way to implement the same thing (and would require unique argument IDs within the same class ancestry). </p> </div> </div> <div class="NAVFOOTER"> <br> <br> <table width="100%" border="0" bgcolor="#ffffff" cellpadding= "1" cellspacing="0"> <tr> <td width="25%" bgcolor="#ffffff" align="left"> <a href="z109.html"><font color="#0000ff" size="2"><b> <<< Previous</b></font></a> </td> <td width="25%" colspan="2" bgcolor="#ffffff" align= "center"> <font color="#0000ff" size="2"><b><a href="ggad.html"> <font color="#0000ff" size="2"><b> Home</b></font></a></b></font> </td> <td width="25%" bgcolor="#ffffff" align="right"> <a href="sec-objectdata.html"><font color="#0000ff" size="2"><b>Next >>></b></font></a> </td> </tr> <tr> <td colspan="2" align="left"> <font color="#000000" size="2"><b>Signals</b></font> </td> <td colspan="2" align="right"> <font color="#000000" size="2"><b>Attaching Data to Objects</b></font> </td> </tr> </table> </div> </body></html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -