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