Next: 2.5 The GSMarkup NSBundle
Up: 2. The GNUstep Markup
Previous: 2.3 The objects section
Subsections
The connectors section is used to establish connections between
objects.
Objects are identified by their id. There are various ways
in which an object can be given an id:
Any object which has been given an id can be the source or the target
of a connection set up in the connectors section.
Inside the connectors section tags are interpreted in a different way
than inside the objects section. Inside the connectors sections, tags
are interpreted as being connectors tags rather than object tags.
Connector tags might vary, but normally you only need to know about
outlet connectors, so we only describe outlet connectors here.
An outlet connector is created with the <outlet> tag. For
example,
<connectors>
<outlet source="#NSOwner" target="#Controller" key="controller" />
</connectors>
An outlet has a source (an object specified by id), a target (another
object again specified by id), and a key (a string). The outlet
describes a connection which should be established between the source
and target object; the key represents a key in the source object. By
using key-value coding, when the outlet connection is established, the
value for the key in the source is set to the target (I'll try to
explain this better in a minute). In the example, when the outlet is
established, it's result will likely to be to invoke
[#NSOwner setController: #Controller];
(where #NSOwner is the object which has id NSOwner
and #Controller is the object which has id
Controller).
As an advanced extension, if the source or target of
an outlet connector contains a dot (that is, the '.'
character), then the part of the string before the dot is interpreted
as an object specified by id, and the part of the string after the dot
is interpreted as a key value path to use on the object to get the
actual source or target. For example, when the outlet
<connectors>
<outlet source="#NSOwner" target="#Controller.name" key="controllerName" />
</connectors>
is established, it's result will likely to be to invoke
[#NSOwner setControllerName: [#Controller name]];
assuming that #Controller responds to a method
name (if it doesn't, key-value coding - as explained
in the next section - is used to retrieve the value for key
name of the object #Controller).
When an outlet connection is established, the following things happen:
- the outlet connector determines the source and target objects
from their ids (by performing a lookup in the name tables which
store the mappings from ids to objects). If the ids do not contains
dots, a simple lookup in the name table is done. If the source or
target strings contain a dot, then the advanced key value coding
support is used: the string is broken in two parts: before and after
the first dot in the string. For example,
#NSController.delegate.name would be broken into
#NSController and delegate.name. The first part
of the string is looked up in the name table, producing an object.
Then, key value coding is used to retrieve the value for the key
path given by the second string on this object. In practice, if the
first part of the string is xxx, and the second part is
yyy, the source or target is set to the
result of the following operations:
[[nameTable objectForKey: xxx] valueForKeyPath: yyy];
(please check the documentation for valueForKeyPath: to
learn more about this operation).
- the outlet connector calls
[source takeValue: target forKey: key];
to set target as the value for the key key in the source. If you
don't know what this really mean, we describe here briefly what this
does; for more information please read the documentation of the
takeValue:forKey: method.
- if the key is xxx, the system searches for the setXxx:
method in the source (please note that the first letter of xxx is
made uppercase). If that method exists, the following code is
executed:
[source setXxx: target];
and the outlet connection can be considered established.
- if the method wasn't found, the _setXxx: method is
searched, and if it exists is used.
- if this fails, the system searches an instance variable with
name _xxx in the source, and if it finds it, it
ASSIGNs to it the target2.3. Assigning includes
releasing the previous value, and retaining the new one.
- if the _xxx instance variable is not found, the system
searches for an instance variable called xxx, and tries to
set that.
- if even this fails, the system calls the method
-handleTakeValue:forUnboundKey: of the source, which -
unless overridden by the source class - raises an exception.
As you can see, you can automatically set up instance variables of
objects to point to other objects when you load a gsmarkup file. This is
very handy to establish connections between objects.
Next: 2.5 The GSMarkup NSBundle
Up: 2. The GNUstep Markup
Previous: 2.3 The objects section
2008-03-19