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)->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->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->filename); 489 self->filename = g_value_dup_string (value); 490 g_print ("filename: %s\n", self->filename); 491 break; 492 493 case PROP_ZOOM_LEVEL: 494 self->zoom_level = g_value_get_uint (value); 495 g_print ("zoom level: %u\n", self->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->filename); 517 break; 518 519 case PROP_ZOOM_LEVEL: 520 g_value_set_uint (value, self->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->set_property = viewer_file_set_property; 536 object_class->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 (&val, G_TYPE_UINT); 569g_value_set_char (&val, 11); 570 571g_object_set_property (G_OBJECT (file), "zoom-level", &val); 572 573g_value_unset (&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