• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<?xml version='1.0' encoding="UTF-8"?>
2<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
3               "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
4]>
5<chapter id="chapter-gobject">
6  <title>The GObject base class</title>
7
8  <para>
9    The previous chapter discussed the details of GLib's Dynamic Type System.
10    The GObject library also contains an implementation for a base fundamental
11    type named <link linkend="GObject"><type>GObject</type></link>.
12  </para>
13
14  <para>
15    <link linkend="GObject"><type>GObject</type></link> is a fundamental classed instantiable type. It implements:
16    <itemizedlist>
17      <listitem><para>Memory management with reference counting</para></listitem>
18      <listitem><para>Construction/Destruction of instances</para></listitem>
19      <listitem><para>Generic per-object properties with set/get function pairs</para></listitem>
20      <listitem><para>Easy use of signals</para></listitem>
21    </itemizedlist>
22    All the GNOME libraries which use the GLib type system (like GTK+ and GStreamer)
23    inherit from <link linkend="GObject"><type>GObject</type></link> which is why it is important to understand
24    the details of how it works.
25  </para>
26
27  <sect1 id="gobject-instantiation">
28    <title>Object instantiation</title>
29
30    <para>
31      The <function><link linkend="g-object-new">g_object_new</link></function>
32      family of functions can be used to instantiate any GType which inherits
33      from the GObject base type. All these functions make sure the class and
34      instance structures have been correctly initialized by GLib's type system
35      and then invoke at one point or another the constructor class method
36      which is used to:
37      <itemizedlist>
38        <listitem><para>
39            Allocate and clear memory through <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>,
40          </para></listitem>
41        <listitem><para>
42            Initialize the object's instance with the construction properties.
43          </para></listitem>
44      </itemizedlist>
45     Although one can expect all class and instance members (except the fields
46     pointing to the parents) to be set to zero, some consider it good practice
47     to explicitly set them.
48    </para>
49
50    <para>
51      Once all construction operations have been completed and constructor
52      properties set, the constructed class method is called.
53    </para>
54
55    <para>
56      Objects which inherit from GObject are allowed to override this
57      constructed class method.
58      The example below shows how <type>ViewerFile</type> overrides the parent's construction process:
59<informalexample><programlisting>
60#define VIEWER_TYPE_FILE viewer_file_get_type ()
61G_DECLARE_FINAL_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)
62
63struct _ViewerFile
64{
65  GObject parent_instance;
66
67  /* instance members */
68};
69
70/* will create viewer_file_get_type and set viewer_file_parent_class */
71G_DEFINE_TYPE (ViewerFile, viewer_file, G_TYPE_OBJECT)
72
73static void
74viewer_file_constructed (GObject *obj)
75{
76  /* update the object state depending on constructor properties */
77
78  /* Always chain up to the parent constructed function to complete object
79   * initialisation. */
80  G_OBJECT_CLASS (viewer_file_parent_class)-&gt;constructed (obj);
81}
82
83static void
84viewer_file_class_init (ViewerFileClass *klass)
85{
86  GObjectClass *object_class = G_OBJECT_CLASS (klass);
87
88  object_class-&gt;constructed = viewer_file_constructed;
89}
90
91static void
92viewer_file_init (ViewerFile *self)
93{
94  /* initialize the object */
95}
96
97</programlisting></informalexample>
98      If the user instantiates an object <type>ViewerFile</type> with:
99<informalexample><programlisting>
100ViewerFile *file = g_object_new (VIEWER_TYPE_FILE, NULL);
101</programlisting></informalexample>
102      If this is the first instantiation of such an object, the
103      <function>viewer_file_class_init</function> function will be invoked
104      after any <function>viewer_file_base_class_init</function> function.
105      This will make sure the class structure of this new object is
106      correctly initialized. Here, <function>viewer_file_class_init</function>
107      is expected to override the object's class methods and setup the
108      class' own methods. In the example above, the <literal>constructed</literal>
109      method is the only overridden method: it is set to
110      <function>viewer_file_constructed</function>.
111    </para>
112
113    <para>
114      Once <function><link linkend="g-object-new">g_object_new</link></function> has obtained a reference to an initialized
115      class structure, it invokes its constructor method to create an instance of the new
116      object, if the constructor has been overridden in <function>viewer_file_class_init</function>.
117      Overridden constructors must chain up to their parent’s constructor. In
118      order to find the parent class and chain up to the parent class
119      constructor, we can use the <literal>viewer_file_parent_class</literal>
120      pointer that has been set up for us by the
121      <link linkend="G-DEFINE-TYPE:CAPS"><literal>G_DEFINE_TYPE</literal></link>
122      macro.
123    </para>
124
125    <para>
126      Finally, at one point or another, <function>g_object_constructor</function> is invoked
127      by the last constructor in the chain. This function allocates the object's instance buffer
128      through <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
129      which means that the <function>instance_init</function> function is invoked at this point if one
130      was registered. After <function>instance_init</function> returns, the object is fully initialized and should be
131      ready to have its methods called by the user. When
132      <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
133      returns, <function>g_object_constructor</function> sets the construction properties
134      (i.e. the properties which were given to <function><link linkend="g-object-new">g_object_new</link></function>) and returns
135      to the user's constructor.
136    </para>
137
138    <para>
139      The process described above might seem a bit complicated, but it can be
140      summarized easily by the table below which lists the functions invoked
141      by <function><link linkend="g-object-new">g_object_new</link></function>
142      and their order of invocation:
143    </para>
144
145    <para>
146      <table id="gobject-construction-table">
147        <title><function><link linkend="g-object-new">g_object_new</link></function></title>
148        <tgroup cols="3">
149          <colspec colwidth="*" colnum="1" align="left"/>
150          <colspec colwidth="*" colnum="2" align="left"/>
151          <colspec colwidth="8*" colnum="3" align="left"/>
152
153          <thead>
154            <row>
155              <entry>Invocation time</entry>
156              <entry>Function invoked</entry>
157              <entry>Function's parameters</entry>
158              <entry>Remark</entry>
159            </row>
160          </thead>
161          <tbody>
162            <row>
163              <entry morerows="3">First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
164              <entry>target type's <function>base_init</function> function</entry>
165              <entry>On the inheritance tree of classes from fundamental type to target type.
166                <function>base_init</function> is invoked once for each class structure.</entry>
167              <entry>Never used in practice. Unlikely you will need it.</entry>
168            </row>
169            <row>
170              <!--entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry-->
171              <entry>target type's <function>class_init</function> function</entry>
172              <entry>On target type's class structure</entry>
173              <entry>
174                Here, you should make sure to initialize or override class methods (that is,
175                assign to each class' method its function pointer) and create the signals and
176                the properties associated to your object.
177              </entry>
178            </row>
179            <row>
180              <!--entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry-->
181              <entry>interface's <function>base_init</function> function</entry>
182              <entry>On interface's vtable</entry>
183              <entry></entry>
184            </row>
185            <row>
186              <!--entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry-->
187              <entry>interface's <function>interface_init</function> function</entry>
188              <entry>On interface's vtable</entry>
189              <entry></entry>
190            </row>
191            <row>
192              <entry morerows="2">Each call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
193              <entry>target type's class <function>constructor</function> method: <function>GObjectClass->constructor</function></entry>
194              <entry>On object's instance</entry>
195              <entry>
196                If you need to handle construct properties in a custom way, or implement a singleton class, override the constructor
197                method and make sure to chain up to the object's
198                parent class before doing your own initialization.
199                In doubt, do not override the constructor method.
200              </entry>
201            </row>
202            <row>
203              <!--entry>Each call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry-->
204              <entry>type's <function>instance_init</function> function</entry>
205              <entry>On the inheritance tree of classes from fundamental type to target type.
206              the <function>instance_init</function> provided for each type is invoked once for each instance
207              structure.</entry>
208              <entry>
209                Provide an <function>instance_init</function> function to initialize your object before its construction
210                properties are set. This is the preferred way to initialize a GObject instance.
211                This function is equivalent to C++ constructors.
212              </entry>
213            </row>
214            <row>
215              <!--entry>Each call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry-->
216              <entry>target type's class <function>constructed</function> method: <function>GObjectClass->constructed</function></entry>
217              <entry>On object's instance</entry>
218              <entry>
219                If you need to perform object initialization steps after all construct properties have been set.
220                This is the final step in the object initialization process, and is only called if the <function>constructor</function>
221                method returned a new object instance (rather than, for example, an existing singleton).
222              </entry>
223            </row>
224          </tbody>
225        </tgroup>
226      </table>
227    </para>
228
229    <para>
230      Readers should feel concerned about one little twist in the order in
231      which functions are invoked: while, technically, the class' constructor
232      method is called <emphasis>before</emphasis> the GType's <function>instance_init</function>
233      function (since <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> which calls <function>instance_init</function> is called by
234      <function>g_object_constructor</function> which is the top-level class
235      constructor method and to which users are expected to chain to), the
236      user's code which runs in a user-provided constructor will always
237      run <emphasis>after</emphasis> GType's <function>instance_init</function> function since the
238      user-provided constructor <emphasis>must</emphasis> (you've been warned)
239      chain up <emphasis>before</emphasis> doing anything useful.
240    </para>
241  </sect1>
242
243  <sect1 id="gobject-memory">
244    <title>Object memory management</title>
245
246    <para>
247      The memory-management API for GObjects is a bit complicated but the idea behind it
248      is pretty simple: the goal is to provide a flexible model based on reference counting
249      which can be integrated in applications which use or require different memory management
250      models (such as garbage collection). The methods which are used to
251      manipulate this reference count are described below.
252    </para>
253
254    <sect2 id="gobject-memory-refcount">
255      <title>Reference count</title>
256
257      <para>
258        The functions <function><link linkend="g-object-ref">g_object_ref</link></function>/<function><link linkend="g-object-unref">g_object_unref</link></function> respectively
259        increase and decrease the reference count. These functions are
260        thread-safe.
261        <function><link linkend="g-clear-object">g_clear_object</link></function>
262        is a convenience wrapper around <function>g_object_unref</function>
263        which also clears the pointer passed to it.
264      </para>
265      <para>
266        The reference count is initialized to one by
267        <function><link linkend="g-object-new">g_object_new</link></function> which means that the caller
268        is currently the sole owner of the newly-created reference.
269        When the reference count reaches zero, that is,
270        when <function><link linkend="g-object-unref">g_object_unref</link></function> is called by the last client holding
271        a reference to the object, the <emphasis>dispose</emphasis> and the
272        <emphasis>finalize</emphasis> class methods are invoked.
273      </para>
274      <para>
275        Finally, after <emphasis>finalize</emphasis> is invoked,
276        <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> is called to free the object instance.
277        Depending on the memory allocation policy decided when the type was registered (through
278        one of the <function>g_type_register_*</function> functions), the object's instance
279        memory will be freed or returned to the object pool for this type.
280        Once the object has been freed, if it was the last instance of the type, the type's class
281        will be destroyed as described in <xref linkend="gtype-instantiable-classed"/> and
282          <xref linkend="gtype-non-instantiable-classed"/>.
283      </para>
284
285      <para>
286        The table below summarizes the destruction process of a GObject:
287        <table id="gobject-destruction-table">
288          <title><function><link linkend="g-object-unref">g_object_unref</link></function></title>
289          <tgroup cols="3">
290            <colspec colwidth="*" colnum="1" align="left"/>
291            <colspec colwidth="*" colnum="2" align="left"/>
292            <colspec colwidth="8*" colnum="3" align="left"/>
293
294            <thead>
295              <row>
296                <entry>Invocation time</entry>
297                <entry>Function invoked</entry>
298                <entry>Function's parameters</entry>
299                <entry>Remark</entry>
300              </row>
301            </thead>
302            <tbody>
303              <row>
304                <entry morerows="1">Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for an instance
305                  of target type
306                 </entry>
307                <entry>target type's dispose class function</entry>
308                <entry>GObject instance</entry>
309                <entry>
310                  When dispose ends, the object should not hold any reference to any other
311                  member object. The object is also expected to be able to answer client
312                  method invocations (with possibly an error code but no memory violation)
313                  until finalize is executed. dispose can be executed more than once.
314                dispose should chain up to its parent implementation just before returning
315                to the caller.
316                </entry>
317              </row>
318              <row>
319                <!--entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for an instance
320                  of target type
321                </entry-->
322                <entry>target type's finalize class function</entry>
323                <entry>GObject instance</entry>
324                <entry>
325                  Finalize is expected to complete the destruction process initiated by
326                  dispose. It should complete the object's destruction. finalize will be
327                  executed only once.
328                finalize should chain up to its parent implementation just before returning
329                to the caller.
330                  The reason why the destruction process is split is two different phases is
331                  explained in <xref linkend="gobject-memory-cycles"/>.
332                </entry>
333              </row>
334              <row>
335                <entry morerows="3">Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for the last
336                  instance of target type
337                 </entry>
338                <entry>interface's <function>interface_finalize</function> function</entry>
339                <entry>On interface's vtable</entry>
340                <entry>Never used in practice. Unlikely you will need it.</entry>
341              </row>
342              <row>
343                <!--entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function>for the last
344                  instance of target type
345                 </entry-->
346                <entry>interface's <function>base_finalize</function> function</entry>
347                <entry>On interface's vtable</entry>
348                <entry>Never used in practice. Unlikely you will need it.</entry>
349              </row>
350              <row>
351                <!--entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for the last
352                  instance of target type
353                 </entry-->
354                <entry>target type's <function>class_finalize</function> function</entry>
355                <entry>On target type's class structure</entry>
356                <entry>Never used in practice. Unlikely you will need it.</entry>
357              </row>
358              <row>
359                <!--entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for the last
360                  instance of target type
361                 </entry-->
362                <entry>type's <function>base_finalize</function> function</entry>
363                <entry>On the inheritance tree of classes from fundamental type to target type.
364                  <function>base_init</function> is invoked once for each class structure.</entry>
365                <entry>Never used in practice. Unlikely you will need it.</entry>
366              </row>
367            </tbody>
368          </tgroup>
369        </table>
370      </para>
371
372    </sect2>
373
374    <sect2 id="gobject-memory-weakref">
375      <title>Weak References</title>
376
377      <para>
378      Weak references are used to monitor object finalization:
379      <function><link linkend="g-object-weak-ref">g_object_weak_ref</link></function> adds a monitoring callback which does
380      not hold a reference to the object but which is invoked when the object runs
381      its dispose method. As such, each weak ref can be invoked more than once upon
382      object finalization (since dispose can run more than once during object
383      finalization).
384      </para>
385
386      <para>
387        <function><link linkend="g-object-weak-unref">g_object_weak_unref</link></function> can be used to remove a monitoring
388        callback from the object.
389      </para>
390
391      <para>
392        Weak references are also used to implement <function><link linkend="g-object-add-weak-pointer">g_object_add_weak_pointer</link></function>
393        and <function><link linkend="g-object-remove-weak-pointer">g_object_remove_weak_pointer</link></function>. These functions add a weak reference
394        to the object they are applied to which makes sure to nullify the pointer given by the user
395        when object is finalized.
396      </para>
397
398      <para>
399        Similarly, <link linkend="GWeakRef"><type>GWeakRef</type></link> can be
400        used to implement weak references if thread safety is required.
401      </para>
402    </sect2>
403
404    <sect2 id="gobject-memory-cycles">
405      <title>Reference counts and cycles</title>
406
407      <para>
408        GObject's memory management model was designed to be easily integrated in existing code
409        using garbage collection. This is why the destruction process is split in two phases:
410        the first phase, executed in the dispose handler is supposed to release all references
411        to other member objects. The second phase, executed by the finalize handler is supposed
412        to complete the object's destruction process. Object methods should be able to run
413        without program error in-between the two phases.
414      </para>
415
416      <para>
417        This two-step destruction process is very useful to break reference counting cycles.
418        While the detection of the cycles is up to the external code, once the cycles have been
419        detected, the external code can invoke <function><link linkend="g-object-run-dispose">g_object_run_dispose</link></function> which
420        will indeed break any existing cycles since it will run the dispose handler associated
421        to the object and thus release all references to other objects.
422      </para>
423
424      <para>
425        This explains one of the rules about the dispose handler stated earlier:
426        the dispose handler can be invoked multiple times. Let's say we
427        have a reference count cycle: object A references B which itself references object A.
428        Let's say we have detected the cycle and we want to destroy the two objects. One way to
429        do this would be to invoke <function><link linkend="g-object-run-dispose">g_object_run_dispose</link></function> on one of the
430        objects.
431      </para>
432
433      <para>
434        If object A releases all its references to all objects, this means it releases its
435        reference to object B. If object B was not owned by anyone else, this is its last
436        reference count which means this last unref runs B's dispose handler which, in turn,
437        releases B's reference on object A. If this is A's last reference count, this last
438        unref runs A's dispose handler which is running for the second time before
439        A's finalize handler is invoked !
440      </para>
441
442      <para>
443        The above example, which might seem a bit contrived, can really happen if
444        GObjects are being handled by language bindings — hence the rules for
445        object destruction should be closely followed.
446      </para>
447    </sect2>
448  </sect1>
449
450  <sect1 id="gobject-properties">
451    <title>Object properties</title>
452
453    <para>
454      One of GObject's nice features is its generic get/set mechanism for object
455      properties. When an object
456      is instantiated, the object's <function>class_init</function> handler should be used to register
457      the object's properties with <function><link linkend="g-object-class-install-properties">g_object_class_install_properties</link></function>.
458    </para>
459
460    <para>
461      The best way to understand how object properties work is by looking at a real example
462      of how it is used:
463<informalexample><programlisting>
464/************************************************/
465/* Implementation                               */
466/************************************************/
467
468enum
469{
470  PROP_FILENAME = 1,
471  PROP_ZOOM_LEVEL,
472  N_PROPERTIES
473};
474
475static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
476
477static void
478viewer_file_set_property (GObject      *object,
479                          guint         property_id,
480                          const GValue *value,
481                          GParamSpec   *pspec)
482{
483  ViewerFile *self = VIEWER_FILE (object);
484
485  switch (property_id)
486    {
487    case PROP_FILENAME:
488      g_free (self-&gt;filename);
489      self-&gt;filename = g_value_dup_string (value);
490      g_print ("filename: %s\n", self-&gt;filename);
491      break;
492
493    case PROP_ZOOM_LEVEL:
494      self-&gt;zoom_level = g_value_get_uint (value);
495      g_print ("zoom level: &percnt;u\n", self-&gt;zoom_level);
496      break;
497
498    default:
499      /* We don't have any other property... */
500      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
501      break;
502    }
503}
504
505static void
506viewer_file_get_property (GObject    *object,
507                          guint       property_id,
508                          GValue     *value,
509                          GParamSpec *pspec)
510{
511  ViewerFile *self = VIEWER_FILE (object);
512
513  switch (property_id)
514    {
515    case PROP_FILENAME:
516      g_value_set_string (value, self-&gt;filename);
517      break;
518
519    case PROP_ZOOM_LEVEL:
520      g_value_set_uint (value, self-&gt;zoom_level);
521      break;
522
523    default:
524      /* We don't have any other property... */
525      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
526      break;
527    }
528}
529
530static void
531viewer_file_class_init (ViewerFileClass *klass)
532{
533  GObjectClass *object_class = G_OBJECT_CLASS (klass);
534
535  object_class-&gt;set_property = viewer_file_set_property;
536  object_class-&gt;get_property = viewer_file_get_property;
537
538  obj_properties[PROP_FILENAME] =
539    g_param_spec_string ("filename",
540                         "Filename",
541                         "Name of the file to load and display from.",
542                         NULL  /* default value */,
543                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
544
545  obj_properties[PROP_ZOOM_LEVEL] =
546    g_param_spec_uint ("zoom-level",
547                       "Zoom level",
548                       "Zoom level to view the file at.",
549                       0  /* minimum value */,
550                       10 /* maximum value */,
551                       2  /* default value */,
552                       G_PARAM_READWRITE);
553
554  g_object_class_install_properties (object_class,
555                                     N_PROPERTIES,
556                                     obj_properties);
557}
558
559/************************************************/
560/* Use                                          */
561/************************************************/
562
563ViewerFile *file;
564GValue val = G_VALUE_INIT;
565
566file = g_object_new (VIEWER_TYPE_FILE, NULL);
567
568g_value_init (&amp;val, G_TYPE_UINT);
569g_value_set_char (&amp;val, 11);
570
571g_object_set_property (G_OBJECT (file), "zoom-level", &amp;val);
572
573g_value_unset (&amp;val);
574</programlisting></informalexample>
575      The client code above looks simple but a lot of things happen under the hood:
576    </para>
577
578    <para>
579      <function><link linkend="g-object-set-property">g_object_set_property</link></function> first ensures a property
580      with this name was registered in <emphasis>file</emphasis>'s <function>class_init</function> handler. If so it walks the class hierarchy,
581      from bottom-most most-derived type, to top-most fundamental type to find the class
582      which registered that property. It then tries to convert the user-provided
583      <link linkend="GValue"><type>GValue</type></link>
584      into a <type>GValue</type> whose type is that of the associated property.
585    </para>
586
587    <para>
588      If the user provides a <type>signed char</type> <type>GValue</type>, as is shown
589      here, and if the object's property was registered as an <type>unsigned int</type>,
590      <function><link linkend="g-value-transform">g_value_transform</link></function> will try to transform the input signed char into
591      an unsigned int. Of course, the success of the transformation depends on the availability
592      of the required transform function. In practice, there will almost always be a transformation
593      <footnote>
594        <para>Its behaviour might not be what you expect but it is up to you to actually avoid
595          relying on these transformations.
596        </para>
597      </footnote>
598      which matches and conversion will be carried out if needed.
599    </para>
600
601    <para>
602      After transformation, the <link linkend="GValue"><type>GValue</type></link> is validated by
603      <function><link linkend="g-param-value-validate">g_param_value_validate</link></function> which makes sure the user's
604      data stored in the <link linkend="GValue"><type>GValue</type></link> matches the characteristics specified by
605      the property's <link linkend="GParamSpec"><type>GParamSpec</type></link>.
606      Here, the <link linkend="GParamSpec"><type>GParamSpec</type></link> we
607      provided in <function>class_init</function> has a validation function which makes sure that the GValue
608      contains a value which respects the minimum and maximum bounds of the
609      <link linkend="GParamSpec"><type>GParamSpec</type></link>. In the example above, the client's GValue does not
610      respect these constraints (it is set to 11, while the maximum is 10). As such, the
611      <function><link linkend="g-object-set-property">g_object_set_property</link></function> function will return with an error.
612    </para>
613
614    <para>
615      If the user's GValue had been set to a valid value, <function><link linkend="g-object-set-property">g_object_set_property</link></function>
616      would have proceeded with calling the object's
617      <function>set_property</function> class method. Here, since our
618      implementation of <type>ViewerFile</type> did override this method, execution would jump to
619      <function>viewer_file_set_property</function> after having retrieved from the
620      <link linkend="GParamSpec"><type>GParamSpec</type></link> the <emphasis>param_id</emphasis>
621      <footnote>
622        <para>
623          It should be noted that the param_id used here need only to uniquely identify each
624          <link linkend="GParamSpec"><type>GParamSpec</type></link> within the <type>ViewerFileClass</type> such that the switch
625          used in the set and get methods actually works. Of course, this locally-unique
626          integer is purely an optimization: it would have been possible to use a set of
627          <emphasis>if (strcmp (a, b) == 0) {} else if (strcmp (a, b) == 0) {}</emphasis> statements.
628        </para>
629      </footnote>
630      which had been stored by
631      <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>.
632    </para>
633
634    <para>
635      Once the property has been set by the object's
636      <function>set_property</function> class method, execution
637      returns to <function><link linkend="g-object-set-property">g_object_set_property</link></function> which makes sure that
638      the "notify" signal is emitted on the object's instance with the changed property as
639      parameter unless notifications were frozen by <function><link linkend="g-object-freeze-notify">g_object_freeze_notify</link></function>.
640    </para>
641
642    <para>
643      <function><link linkend="g-object-thaw-notify">g_object_thaw_notify</link></function> can be used to re-enable notification of
644      property modifications through the
645      <link linkend="GObject-notify"><type>“notify”</type></link> signal. It is important to remember that
646      even if properties are changed while property change notification is frozen, the "notify"
647      signal will be emitted once for each of these changed properties as soon as the property
648      change notification is thawed: no property change is lost for the "notify"
649      signal, although multiple notifications for a single property are
650      compressed. Signals can only be delayed by the notification freezing
651      mechanism.
652    </para>
653
654    <para>
655      It sounds like a tedious task to set up GValues every time when one wants to modify a property.
656      In practice one will rarely do this. The functions <function><link linkend="g-object-set-property">g_object_set_property</link></function>
657      and <function><link linkend="g-object-get-property">g_object_get_property</link></function>
658      are meant to be used by language bindings. For application there is an easier way and
659      that is described next.
660    </para>
661
662    <sect2 id="gobject-multi-properties">
663      <title>Accessing multiple properties at once</title>
664
665      <para>
666        It is interesting to note that the <function><link linkend="g-object-set">g_object_set</link></function> and
667        <function><link linkend="g-object-set-valist">g_object_set_valist</link></function> (variadic version) functions can be used to set
668        multiple properties at once. The client code shown above can then be re-written as:
669<informalexample><programlisting>
670ViewerFile *file;
671file = /* */;
672g_object_set (G_OBJECT (file),
673              "zoom-level", 6,
674              "filename", "~/some-file.txt",
675              NULL);
676</programlisting></informalexample>
677        This saves us from managing the GValues that we were needing to handle when using
678        <function><link linkend="g-object-set-property">g_object_set_property</link></function>.
679        The code above will trigger one notify signal emission for each property modified.
680      </para>
681
682      <para>
683        Equivalent <function>_get</function> versions are also available:
684        <function><link linkend="g-object-get">g_object_get</link></function>
685        and <function><link linkend="g-object-get-valist">g_object_get_valist</link></function> (variadic version) can be used to get numerous
686        properties at once.
687      </para>
688
689      <para>
690        These high level functions have one drawback — they don't provide a return value.
691        One should pay attention to the argument types and ranges when using them.
692        A known source of errors is to pass a different type from what the
693        property expects; for instance, passing an integer when the property
694        expects a floating point value and thus shifting all subsequent parameters
695        by some number of bytes. Also forgetting the terminating
696        <literal>NULL</literal> will lead to undefined behaviour.
697      </para>
698
699      <para>
700        This explains how <function><link linkend="g-object-new">g_object_new</link></function>,
701        <function><link linkend="g-object-newv">g_object_newv</link></function> and <function><link linkend="g-object-new-valist">g_object_new_valist</link></function>
702        work: they parse the user-provided variable number of parameters and invoke
703        <function><link linkend="g-object-set">g_object_set</link></function> on the parameters only after the object has been successfully constructed.
704        The "notify" signal will be emitted for each property set.
705      </para>
706
707    </sect2>
708
709<!-- @todo tell here about how to pass use handle properties in derived classes -->
710
711  </sect1>
712
713</chapter>
714