⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sec-finalization.html

📁 GTK+_ Gnome Application Development
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html>  <head>    <title>      Object Finalization    </title>    <meta name="GENERATOR" content=    "Modular DocBook HTML Stylesheet Version 1.45">    <link rel="HOME" title="GTK+ / Gnome Application Development"    href="ggad.html">    <link rel="UP" title="The GTK+ Object and Type System" href=     "cha-objects.html">    <link rel="PREVIOUS" title="Signals" href="z109.html">    <link rel="NEXT" title="Attaching Data to Objects" href=     "sec-objectdata.html">  </head>  <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink=   "#840084" alink="#0000FF">    <div class="NAVHEADER">      <table width="100%" border="0" bgcolor="#ffffff" cellpadding=       "1" cellspacing="0">        <tr>          <th colspan="4" align="center">            <font color="#000000" size="2">GTK+ / Gnome Application            Development</font>          </th>        </tr>        <tr>          <td width="25%" bgcolor="#ffffff" align="left">            <a href="z109.html"><font color="#0000ff" size="2"><b>            &lt;&lt;&lt; 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 &gt;&gt;&gt;</b></font></a>          </td>        </tr>      </table>    </div>    <div class="SECT1">      <h1 class="SECT1">        <a name="SEC-FINALIZATION">Object Finalization</a>      </h1>      <p>        To write a <span class="STRUCTNAME">GtkObject</span>, you        must implement the methods provided by the <span class=         "STRUCTNAME">GtkObject</span> interface, or at least be        sure you are happy with the default implementations. There        are only five <span class="STRUCTNAME">GtkObject</span>        methods; two of them are <span class="STRUCTNAME">        get_arg</span> and <span class="STRUCTNAME">set_arg</span>,        described in <a href="hc-objectargs.html#SEC-GETSETARG">the        section called <i>Using Object Arguments in Your Own <span        class="STRUCTNAME">GtkObject</span> Subclass</i></a>. The        other three implement object destruction; here are the        fields in <span class="STRUCTNAME">GtkObjectClass</span>:      </p>      <table border="0" bgcolor="#E0E0E0" width="100%">        <tr>          <td><pre class="PROGRAMLISTING">&#13;  void (* shutdown) (GtkObject *object);  void (* destroy)  (GtkObject *object);    void (* finalize) (GtkObject *object);&#13;</pre>          </td>        </tr>      </table>      <p>        As you might guess from this, objects are destroyed in a        three-stage process. Each method represents one stage in        the process; if your object subclass overrides any of them,        it must "chain up" to the corresponding method in the        parent class (see <a href=        "sec-finalization.html#SEC-CHAINUP">the section called <i>        Chaining Up</i></a>). The three methods do the following:      </p>      <ul>        <li>          <p>            The <span class="STRUCTNAME">shutdown</span> method            allows objects to perform actions before destruction            begins. Most subclasses do not override this method;            the default <span class="STRUCTNAME">shutdown</span>            method emits the <span class="SYMBOL">"destroy"</span>            signal to start the next phase. (The default            implementation will <i class="EMPHASIS">always</i> be            invoked, even if overridden, because subclasses are            required to "chain up.")&#13;          </p>        </li>        <li>          <p>            The <span class="STRUCTNAME">destroy</span> method            marks the object "useless" and cleans up associated            resources, but does not free the object itself.            Typically a destroy method would free data, strings,            and so on stored in the instance struct, and set the            struct members to <span class="STRUCTNAME">NULL</span>.            This is the method most subclasses override.&#13;          </p>        </li>        <li>          <p>            The <span class="STRUCTNAME">finalize</span> method is            invoked <i class="EMPHASIS">only when the object's            reference count reaches 0</i>. The default            implementation frees the object instance struct, so            that further attempts to use the object result in a            segmentation fault. The <span class="STRUCTNAME">            finalize</span> method must also consider that user            code could have been invoked after the <span class=             "STRUCTNAME">destroy</span> method, and free any data            that user code could have allocated. &#13;          </p>        </li>      </ul>      <p>        Note: <i class="EMPHASIS">Objects can be destroyed        regardless of their reference count</i>. This means that        the <span class="STRUCTNAME">shutdown</span> method is        invoked and the <span class="STRUCTNAME">destroy</span>        signal is emitted. However, as long as the reference count        is greater than 0, the object will not be <i class=        "EMPHASIS">finalized</i>.      </p>      <p>        The <span class="STRUCTNAME">shutdown</span> method has no        defined role; its purpose depends on the particular object.        For example, the <tt class="CLASSNAME">GtkWidget</tt>        shutdown implementation removes the widget from its parent        container, and unrealizes the widget. This is especially        important for containers: their <span class="STRUCTNAME">        destroy</span> method destroys all children of the        container. If the container was not unrealized before        destruction, it would still be visible and the user would        see each child disappear, followed by the container. With        the <span class="STRUCTNAME">shutdown</span> method,        everything disappears at once.      </p>      <p>        The <span class="STRUCTNAME">destroy</span> method frees as        many resources as possible without rendering the object        "unsafe." If your object has invariants describing its        integrity, a <span class="STRUCTNAME">destroy</span> method        will not violate them. All public functions exported by an        object implementation should gracefully handle destroyed        objects (they should not crash---remember that an object        can be destroyed while references to it persist). The <span        class="STRUCTNAME">finalize</span> method actually frees        the object, meaning that attempts to use the object become        dangerous bugs.      </p>      <p>        The statement that "public functions exported by an object        implementation should gracefully handle destroyed objects"        requires some qualification. This is the intended behavior;        otherwise, code could not ensure the sanity of an object by        increasing its reference count. However, the implementation        does not yet live up to the guarantee in all cases. Some        public functions in GTK+ and Gnome still assume data        structures freed in the destroy method exist, or        re-allocate data structures the destroy method already        freed. Unless the finalize method re-frees those data        structures, they will be leaked. To avoid these bugs, it is        best to avoid calling functions on destroyed objects (in        practice, it would be uncommon to do so).      </p>      <p>        You <i class="EMPHASIS">can</i> count on being able to        check the type and object flags of a destroyed object,        however; and it is certainly safe to call <tt class=         "FUNCTION">gtk_object_unref()</tt> on a destroyed object.        In your own object implementations, be sure you implement        each public function correctly; check whether the object is        destroyed with <tt class="FUNCTION">        GTK_OBJECT_DESTROYED()</tt>, and keep in mind that user        code can run between the <span class="STRUCTNAME">        destroy</span> method and the <span class="STRUCTNAME">        finalize</span> method.      </p>      <p>        Notice that the <span class="STRUCTNAME">destroy</span>        method is the default handler for a <span class="SYMBOL">        "destroy"</span> signal, but the <span class="STRUCTNAME">        shutdown</span> and <span class="STRUCTNAME">        finalize</span> methods are class functions only. This        reduces the complexity and increases the speed of the        finalization process. Also, because <span class=        "STRUCTNAME">finalize</span> destroys the integrity of an        object, it would be unsafe to emit as a signal (GTK+ does        have a facility called "weak references" that allows you to        invoke a callback when an object is finalized---weak        references do not assume that the <span class="STRUCTNAME">        GtkObject</span> is in a sane state).      </p>      <p>        To make things more concrete, let's look at the functions        you would use to destroy an object. First, <tt class=         "FUNCTION">gtk_object_destroy()</tt>:      </p>      <table border="0" bgcolor="#E0E0E0" width="100%">        <tr>          <td><pre class="PROGRAMLISTING">&#13;voidgtk_object_destroy (GtkObject *object){  g_return_if_fail (object != NULL);  g_return_if_fail (GTK_IS_OBJECT (object));  g_return_if_fail (GTK_OBJECT_CONSTRUCTED (object));    if (!GTK_OBJECT_DESTROYED (object))    {      gtk_object_ref (object);      object-&gt;klass-&gt;shutdown (object);      gtk_object_unref (object);    }}&#13;</pre>          </td>        </tr>      </table>      <p>        Notice that destroyed-but-not-finalized objects are        flagged, and this flag can be checked with the <tt class=         "FUNCTION">GTK_OBJECT_DESTROYED()</tt> macro. <tt class=         "FUNCTION">gtk_object_destroy()</tt> ensures that objects        are not destroyed twice by ignoring any already-destroyed        objects. If an object has not been destroyed, <tt class=         "FUNCTION">gtk_object_destroy()</tt> references it to        prevent finalization during the destroy process and invokes        the shutdown method; by default, that method looks like        this:      </p>      <table border="0" bgcolor="#E0E0E0" width="100%">        <tr>          <td><pre class="PROGRAMLISTING">&#13;static voidgtk_object_shutdown (GtkObject *object){  GTK_OBJECT_SET_FLAGS (object, GTK_DESTROYED);  gtk_signal_emit (object, object_signals[DESTROY]);}&#13;</pre>          </td>        </tr>      </table>      <p>        This method sets the destroyed flag, to ensure that any        recursive <tt class="FUNCTION">gtk_object_destroy()</tt>        calls have no effect; then it emits the <span class=        "SYMBOL">"destroy"</span> signal. <tt class="FUNCTION">        gtk_object_shutdown()</tt> seems pointless by itself;        however, subclasses may override this method with something        more substantial, chaining up to the <span class=        "STRUCTNAME">GtkObject</span> default method (see <a href=         "sec-finalization.html#SEC-CHAINUP">the section called <i>        Chaining Up</i></a>).      </p>      <p>        It may be unclear that <tt class="FUNCTION">        gtk_object_shutdown()</tt> is a method implementation,        while <tt class="FUNCTION">gtk_object_destroy()</tt> is a        public function. Note that <tt class="FUNCTION">        gtk_object_shutdown()</tt> is the internal function that        implements the <span class="STRUCTNAME">shutdown</span>        method for the <span class="STRUCTNAME">GtkObject</span>        class, while <tt class="FUNCTION">gtk_object_destroy()</tt>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -