diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/doc/objc.texi | |
download | cbb-gcc-4.6.4-15d2061ac0796199866debe9ac87130894b0cdd3.tar.bz2 cbb-gcc-4.6.4-15d2061ac0796199866debe9ac87130894b0cdd3.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'gcc/doc/objc.texi')
-rw-r--r-- | gcc/doc/objc.texi | 1227 |
1 files changed, 1227 insertions, 0 deletions
diff --git a/gcc/doc/objc.texi b/gcc/doc/objc.texi new file mode 100644 index 000000000..5d750386a --- /dev/null +++ b/gcc/doc/objc.texi @@ -0,0 +1,1227 @@ +@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, +@c 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2010 +@c Free Software Foundation, Inc. +@c This is part of the GCC manual. +@c For copying conditions, see the file gcc.texi. + +@node Objective-C +@comment node-name, next, previous, up + +@chapter GNU Objective-C features + +This document is meant to describe some of the GNU Objective-C +features. It is not intended to teach you Objective-C. There are +several resources on the Internet that present the language. + +@menu +* GNU Objective-C runtime API:: +* Executing code before main:: +* Type encoding:: +* Garbage Collection:: +* Constant string objects:: +* compatibility_alias:: +* Exceptions:: +* Synchronization:: +* Fast enumeration:: +* Messaging with the GNU Objective-C runtime:: +@end menu + +@c ========================================================================= +@node GNU Objective-C runtime API +@section GNU Objective-C runtime API + +This section is specific for the GNU Objective-C runtime. If you are +using a different runtime, you can skip it. + +The GNU Objective-C runtime provides an API that allows you to +interact with the Objective-C runtime system, querying the live +runtime structures and even manipulating them. This allows you for +example to inspect and navigate classes, methods and protocols; to +define new classes or new methods, and even to modify existing classes +or protocols. + +If you are using a ``Foundation'' library such as GNUstep-Base, this +library will provide you with a rich set of functionality to do most +of the inspection tasks, and you probably will only need direct access +to the GNU Objective-C runtime API to define new classes or methods. + +@menu +* Modern GNU Objective-C runtime API:: +* Traditional GNU Objective-C runtime API:: +@end menu + +@c ========================================================================= +@node Modern GNU Objective-C runtime API +@subsection Modern GNU Objective-C runtime API + +The GNU Objective-C runtime provides an API which is similar to the +one provided by the ``Objective-C 2.0'' Apple/NeXT Objective-C +runtime. The API is documented in the public header files of the GNU +Objective-C runtime: + +@itemize @bullet + +@item +@file{objc/objc.h}: this is the basic Objective-C header file, +defining the basic Objective-C types such as @code{id}, @code{Class} +and @code{BOOL}. You have to include this header to do almost +anything with Objective-C. + +@item +@file{objc/runtime.h}: this header declares most of the public runtime +API functions allowing you to inspect and manipulate the Objective-C +runtime data structures. These functions are fairly standardized +across Objective-C runtimes and are almost identical to the Apple/NeXT +Objective-C runtime ones. It does not declare functions in some +specialized areas (constructing and forwarding message invocations, +threading) which are in the other headers below. You have to include +@file{objc/objc.h} and @file{objc/runtime.h} to use any of the +functions, such as @code{class_getName()}, declared in +@file{objc/runtime.h}. + +@item +@file{objc/message.h}: this header declares public functions used to +construct, deconstruct and forward message invocations. Because +messaging is done in quite a different way on different runtimes, +functions in this header are specific to the GNU Objective-C runtime +implementation. + +@item +@file{objc/objc-exception.h}: this header declares some public +functions related to Objective-C exceptions. For example functions in +this header allow you to throw an Objective-C exception from plain +C/C++ code. + +@item +@file{objc/objc-sync.h}: this header declares some public functions +related to the Objective-C @code{@@synchronized()} syntax, allowing +you to emulate an Objective-C @code{@@synchronized()} block in plain +C/C++ code. + +@item +@file{objc/thr.h}: this header declares a public runtime API threading +layer that is only provided by the GNU Objective-C runtime. It +declares functions such as @code{objc_mutex_lock()}, which provide a +platform-independent set of threading functions. + +@end itemize + +The header files contain detailed documentation for each function in +the GNU Objective-C runtime API. + +@c ========================================================================= +@node Traditional GNU Objective-C runtime API +@subsection Traditional GNU Objective-C runtime API + +The GNU Objective-C runtime used to provide a different API, which we +call the ``traditional'' GNU Objective-C runtime API. Functions +belonging to this API are easy to recognize because they use a +different naming convention, such as @code{class_get_super_class()} +(traditional API) instead of @code{class_getSuperclass()} (modern +API). Software using this API includes the file +@file{objc/objc-api.h} where it is declared. + +The traditional API is deprecated but it is still supported in this +release of the runtime; you can access it as usual by including +@file{objc/objc-api.h}. + +If you are using the traditional API you are urged to upgrade your +software to use the modern API because the traditional API requires +access to private runtime internals to do anything serious with it; +for this reason, there is no guarantee that future releases of the GNU +Objective-C runtime library will be able to provide a fully compatible +@file{objc/objc-api.h} as the private runtime internals change. It is +expected that the next release will hide a number of runtime internals +making the traditional API nominally supported but fairly useless +beyond very simple use cases. + +Finally, you can not include both @file{objc/objc-api.h} and +@file{objc/runtime.h} at the same time. The traditional and modern +APIs unfortunately have some conflicting declarations (such as the one +for @code{Method}) and can not be used at the same time. + +@c ========================================================================= +@node Executing code before main +@section @code{+load}: Executing code before main + +This section is specific for the GNU Objective-C runtime. If you are +using a different runtime, you can skip it. + +The GNU Objective-C runtime provides a way that allows you to execute +code before the execution of the program enters the @code{main} +function. The code is executed on a per-class and a per-category basis, +through a special class method @code{+load}. + +This facility is very useful if you want to initialize global variables +which can be accessed by the program directly, without sending a message +to the class first. The usual way to initialize global variables, in the +@code{+initialize} method, might not be useful because +@code{+initialize} is only called when the first message is sent to a +class object, which in some cases could be too late. + +Suppose for example you have a @code{FileStream} class that declares +@code{Stdin}, @code{Stdout} and @code{Stderr} as global variables, like +below: + +@smallexample + +FileStream *Stdin = nil; +FileStream *Stdout = nil; +FileStream *Stderr = nil; + +@@implementation FileStream + ++ (void)initialize +@{ + Stdin = [[FileStream new] initWithFd:0]; + Stdout = [[FileStream new] initWithFd:1]; + Stderr = [[FileStream new] initWithFd:2]; +@} + +/* @r{Other methods here} */ +@@end + +@end smallexample + +In this example, the initialization of @code{Stdin}, @code{Stdout} and +@code{Stderr} in @code{+initialize} occurs too late. The programmer can +send a message to one of these objects before the variables are actually +initialized, thus sending messages to the @code{nil} object. The +@code{+initialize} method which actually initializes the global +variables is not invoked until the first message is sent to the class +object. The solution would require these variables to be initialized +just before entering @code{main}. + +The correct solution of the above problem is to use the @code{+load} +method instead of @code{+initialize}: + +@smallexample + +@@implementation FileStream + ++ (void)load +@{ + Stdin = [[FileStream new] initWithFd:0]; + Stdout = [[FileStream new] initWithFd:1]; + Stderr = [[FileStream new] initWithFd:2]; +@} + +/* @r{Other methods here} */ +@@end + +@end smallexample + +The @code{+load} is a method that is not overridden by categories. If a +class and a category of it both implement @code{+load}, both methods are +invoked. This allows some additional initializations to be performed in +a category. + +This mechanism is not intended to be a replacement for @code{+initialize}. +You should be aware of its limitations when you decide to use it +instead of @code{+initialize}. + +@menu +* What you can and what you cannot do in +load:: +@end menu + + +@node What you can and what you cannot do in +load +@subsection What you can and what you cannot do in @code{+load} + +@code{+load} is to be used only as a last resort. Because it is +executed very early, most of the Objective-C runtime machinery will +not be ready when @code{+load} is executed; hence @code{+load} works +best for executing C code that is independent on the Objective-C +runtime. + +The @code{+load} implementation in the GNU runtime guarantees you the +following things: + +@itemize @bullet + +@item +you can write whatever C code you like; + +@item +you can allocate and send messages to objects whose class is implemented +in the same file; + +@item +the @code{+load} implementation of all super classes of a class are +executed before the @code{+load} of that class is executed; + +@item +the @code{+load} implementation of a class is executed before the +@code{+load} implementation of any category. + +@end itemize + +In particular, the following things, even if they can work in a +particular case, are not guaranteed: + +@itemize @bullet + +@item +allocation of or sending messages to arbitrary objects; + +@item +allocation of or sending messages to objects whose classes have a +category implemented in the same file; + +@item +sending messages to Objective-C constant strings (@code{@@"this is a +constant string"}); + +@end itemize + +You should make no assumptions about receiving @code{+load} in sibling +classes when you write @code{+load} of a class. The order in which +sibling classes receive @code{+load} is not guaranteed. + +The order in which @code{+load} and @code{+initialize} are called could +be problematic if this matters. If you don't allocate objects inside +@code{+load}, it is guaranteed that @code{+load} is called before +@code{+initialize}. If you create an object inside @code{+load} the +@code{+initialize} method of object's class is invoked even if +@code{+load} was not invoked. Note if you explicitly call @code{+load} +on a class, @code{+initialize} will be called first. To avoid possible +problems try to implement only one of these methods. + +The @code{+load} method is also invoked when a bundle is dynamically +loaded into your running program. This happens automatically without any +intervening operation from you. When you write bundles and you need to +write @code{+load} you can safely create and send messages to objects whose +classes already exist in the running program. The same restrictions as +above apply to classes defined in bundle. + + + +@node Type encoding +@section Type encoding + +This is an advanced section. Type encodings are used extensively by +the compiler and by the runtime, but you generally do not need to know +about them to use Objective-C. + +The Objective-C compiler generates type encodings for all the types. +These type encodings are used at runtime to find out information about +selectors and methods and about objects and classes. + +The types are encoded in the following way: + +@c @sp 1 + +@multitable @columnfractions .25 .75 +@item @code{_Bool} +@tab @code{B} +@item @code{char} +@tab @code{c} +@item @code{unsigned char} +@tab @code{C} +@item @code{short} +@tab @code{s} +@item @code{unsigned short} +@tab @code{S} +@item @code{int} +@tab @code{i} +@item @code{unsigned int} +@tab @code{I} +@item @code{long} +@tab @code{l} +@item @code{unsigned long} +@tab @code{L} +@item @code{long long} +@tab @code{q} +@item @code{unsigned long long} +@tab @code{Q} +@item @code{float} +@tab @code{f} +@item @code{double} +@tab @code{d} +@item @code{long double} +@tab @code{D} +@item @code{void} +@tab @code{v} +@item @code{id} +@tab @code{@@} +@item @code{Class} +@tab @code{#} +@item @code{SEL} +@tab @code{:} +@item @code{char*} +@tab @code{*} +@item @code{enum} +@tab an @code{enum} is encoded exactly as the integer type that the compiler uses for it, which depends on the enumeration +values. Often the compiler users @code{unsigned int}, which is then encoded as @code{I}. +@item unknown type +@tab @code{?} +@item Complex types +@tab @code{j} followed by the inner type. For example @code{_Complex double} is encoded as "jd". +@item bit-fields +@tab @code{b} followed by the starting position of the bit-field, the type of the bit-field and the size of the bit-field (the bit-fields encoding was changed from the NeXT's compiler encoding, see below) +@end multitable + +@c @sp 1 + +The encoding of bit-fields has changed to allow bit-fields to be +properly handled by the runtime functions that compute sizes and +alignments of types that contain bit-fields. The previous encoding +contained only the size of the bit-field. Using only this information +it is not possible to reliably compute the size occupied by the +bit-field. This is very important in the presence of the Boehm's +garbage collector because the objects are allocated using the typed +memory facility available in this collector. The typed memory +allocation requires information about where the pointers are located +inside the object. + +The position in the bit-field is the position, counting in bits, of the +bit closest to the beginning of the structure. + +The non-atomic types are encoded as follows: + +@c @sp 1 + +@multitable @columnfractions .2 .8 +@item pointers +@tab @samp{^} followed by the pointed type. +@item arrays +@tab @samp{[} followed by the number of elements in the array followed by the type of the elements followed by @samp{]} +@item structures +@tab @samp{@{} followed by the name of the structure (or @samp{?} if the structure is unnamed), the @samp{=} sign, the type of the members and by @samp{@}} +@item unions +@tab @samp{(} followed by the name of the structure (or @samp{?} if the union is unnamed), the @samp{=} sign, the type of the members followed by @samp{)} +@item vectors +@tab @samp{![} followed by the vector_size (the number of bytes composing the vector) followed by a comma, followed by the alignment (in bytes) of the vector, followed by the type of the elements followed by @samp{]} +@end multitable + +Here are some types and their encodings, as they are generated by the +compiler on an i386 machine: + +@sp 1 + +@multitable @columnfractions .25 .75 +@item Objective-C type +@tab Compiler encoding +@item +@smallexample +int a[10]; +@end smallexample +@tab @code{[10i]} +@item +@smallexample +struct @{ + int i; + float f[3]; + int a:3; + int b:2; + char c; +@} +@end smallexample +@tab @code{@{?=i[3f]b128i3b131i2c@}} +@item +@smallexample +int a __attribute__ ((vector_size (16))); +@end smallexample +@tab @code{![16,16i]} (alignment would depend on the machine) +@end multitable + +@sp 1 + +In addition to the types the compiler also encodes the type +specifiers. The table below describes the encoding of the current +Objective-C type specifiers: + +@sp 1 + +@multitable @columnfractions .25 .75 +@item Specifier +@tab Encoding +@item @code{const} +@tab @code{r} +@item @code{in} +@tab @code{n} +@item @code{inout} +@tab @code{N} +@item @code{out} +@tab @code{o} +@item @code{bycopy} +@tab @code{O} +@item @code{byref} +@tab @code{R} +@item @code{oneway} +@tab @code{V} +@end multitable + +@sp 1 + +The type specifiers are encoded just before the type. Unlike types +however, the type specifiers are only encoded when they appear in method +argument types. + +Note how @code{const} interacts with pointers: + +@sp 1 + +@multitable @columnfractions .25 .75 +@item Objective-C type +@tab Compiler encoding +@item +@smallexample +const int +@end smallexample +@tab @code{ri} +@item +@smallexample +const int* +@end smallexample +@tab @code{^ri} +@item +@smallexample +int *const +@end smallexample +@tab @code{r^i} +@end multitable + +@sp 1 + +@code{const int*} is a pointer to a @code{const int}, and so is +encoded as @code{^ri}. @code{int* const}, instead, is a @code{const} +pointer to an @code{int}, and so is encoded as @code{r^i}. + +Finally, there is a complication when encoding @code{const char *} +versus @code{char * const}. Because @code{char *} is encoded as +@code{*} and not as @code{^c}, there is no way to express the fact +that @code{r} applies to the pointer or to the pointee. + +Hence, it is assumed as a convention that @code{r*} means @code{const +char *} (since it is what is most often meant), and there is no way to +encode @code{char *const}. @code{char *const} would simply be encoded +as @code{*}, and the @code{const} is lost. + +@menu +* Legacy type encoding:: +* @@encode:: +* Method signatures:: +@end menu + +@node Legacy type encoding +@subsection Legacy type encoding + +Unfortunately, historically GCC used to have a number of bugs in its +encoding code. The NeXT runtime expects GCC to emit type encodings in +this historical format (compatible with GCC-3.3), so when using the +NeXT runtime, GCC will introduce on purpose a number of incorrect +encodings: + +@itemize @bullet + +@item +the read-only qualifier of the pointee gets emitted before the '^'. +The read-only qualifier of the pointer itself gets ignored, unless it +is a typedef. Also, the 'r' is only emitted for the outermost type. + +@item +32-bit longs are encoded as 'l' or 'L', but not always. For typedefs, +the compiler uses 'i' or 'I' instead if encoding a struct field or a +pointer. + +@item +@code{enum}s are always encoded as 'i' (int) even if they are actually +unsigned or long. + +@end itemize + +In addition to that, the NeXT runtime uses a different encoding for +bitfields. It encodes them as @code{b} followed by the size, without +a bit offset or the underlying field type. + +@node @@encode +@subsection @@encode + +GNU Objective-C supports the @code{@@encode} syntax that allows you to +create a type encoding from a C/Objective-C type. For example, +@code{@@encode(int)} is compiled by the compiler into @code{"i"}. + +@code{@@encode} does not support type qualifiers other than +@code{const}. For example, @code{@@encode(const char*)} is valid and +is compiled into @code{"r*"}, while @code{@@encode(bycopy char *)} is +invalid and will cause a compilation error. + +@node Method signatures +@subsection Method signatures + +This section documents the encoding of method types, which is rarely +needed to use Objective-C. You should skip it at a first reading; the +runtime provides functions that will work on methods and can walk +through the list of parameters and interpret them for you. These +functions are part of the public ``API'' and are the preferred way to +interact with method signatures from user code. + +But if you need to debug a problem with method signatures and need to +know how they are implemented (i.e., the ``ABI''), read on. + +Methods have their ``signature'' encoded and made available to the +runtime. The ``signature'' encodes all the information required to +dynamically build invocations of the method at runtime: return type +and arguments. + +The ``signature'' is a null-terminated string, composed of the following: + +@itemize @bullet + +@item +The return type, including type qualifiers. For example, a method +returning @code{int} would have @code{i} here. + +@item +The total size (in bytes) required to pass all the parameters. This +includes the two hidden parameters (the object @code{self} and the +method selector @code{_cmd}). + +@item +Each argument, with the type encoding, followed by the offset (in +bytes) of the argument in the list of parameters. + +@end itemize + +For example, a method with no arguments and returning @code{int} would +have the signature @code{i8@@0:4} if the size of a pointer is 4. The +signature is interpreted as follows: the @code{i} is the return type +(an @code{int}), the @code{8} is the total size of the parameters in +bytes (two pointers each of size 4), the @code{@@0} is the first +parameter (an object at byte offset @code{0}) and @code{:4} is the +second parameter (a @code{SEL} at byte offset @code{4}). + +You can easily find more examples by running the ``strings'' program +on an Objective-C object file compiled by GCC. You'll see a lot of +strings that look very much like @code{i8@@0:4}. They are signatures +of Objective-C methods. + + +@node Garbage Collection +@section Garbage Collection + +This section is specific for the GNU Objective-C runtime. If you are +using a different runtime, you can skip it. + +Support for garbage collection with the GNU runtime has been added by +using a powerful conservative garbage collector, known as the +Boehm-Demers-Weiser conservative garbage collector. + +To enable the support for it you have to configure the compiler using +an additional argument, @w{@option{--enable-objc-gc}}. This will +build the boehm-gc library, and build an additional runtime library +which has several enhancements to support the garbage collector. The +new library has a new name, @file{libobjc_gc.a} to not conflict with +the non-garbage-collected library. + +When the garbage collector is used, the objects are allocated using the +so-called typed memory allocation mechanism available in the +Boehm-Demers-Weiser collector. This mode requires precise information on +where pointers are located inside objects. This information is computed +once per class, immediately after the class has been initialized. + +There is a new runtime function @code{class_ivar_set_gcinvisible()} +which can be used to declare a so-called @dfn{weak pointer} +reference. Such a pointer is basically hidden for the garbage collector; +this can be useful in certain situations, especially when you want to +keep track of the allocated objects, yet allow them to be +collected. This kind of pointers can only be members of objects, you +cannot declare a global pointer as a weak reference. Every type which is +a pointer type can be declared a weak pointer, including @code{id}, +@code{Class} and @code{SEL}. + +Here is an example of how to use this feature. Suppose you want to +implement a class whose instances hold a weak pointer reference; the +following class does this: + +@smallexample + +@@interface WeakPointer : Object +@{ + const void* weakPointer; +@} + +- initWithPointer:(const void*)p; +- (const void*)weakPointer; +@@end + + +@@implementation WeakPointer + ++ (void)initialize +@{ + class_ivar_set_gcinvisible (self, "weakPointer", YES); +@} + +- initWithPointer:(const void*)p +@{ + weakPointer = p; + return self; +@} + +- (const void*)weakPointer +@{ + return weakPointer; +@} + +@@end + +@end smallexample + +Weak pointers are supported through a new type character specifier +represented by the @samp{!} character. The +@code{class_ivar_set_gcinvisible()} function adds or removes this +specifier to the string type description of the instance variable named +as argument. + +@c ========================================================================= +@node Constant string objects +@section Constant string objects + +GNU Objective-C provides constant string objects that are generated +directly by the compiler. You declare a constant string object by +prefixing a C constant string with the character @samp{@@}: + +@smallexample + id myString = @@"this is a constant string object"; +@end smallexample + +The constant string objects are by default instances of the +@code{NXConstantString} class which is provided by the GNU Objective-C +runtime. To get the definition of this class you must include the +@file{objc/NXConstStr.h} header file. + +User defined libraries may want to implement their own constant string +class. To be able to support them, the GNU Objective-C compiler provides +a new command line options @option{-fconstant-string-class=@var{class-name}}. +The provided class should adhere to a strict structure, the same +as @code{NXConstantString}'s structure: + +@smallexample + +@@interface MyConstantStringClass +@{ + Class isa; + char *c_string; + unsigned int len; +@} +@@end + +@end smallexample + +@code{NXConstantString} inherits from @code{Object}; user class +libraries may choose to inherit the customized constant string class +from a different class than @code{Object}. There is no requirement in +the methods the constant string class has to implement, but the final +ivar layout of the class must be the compatible with the given +structure. + +When the compiler creates the statically allocated constant string +object, the @code{c_string} field will be filled by the compiler with +the string; the @code{length} field will be filled by the compiler with +the string length; the @code{isa} pointer will be filled with +@code{NULL} by the compiler, and it will later be fixed up automatically +at runtime by the GNU Objective-C runtime library to point to the class +which was set by the @option{-fconstant-string-class} option when the +object file is loaded (if you wonder how it works behind the scenes, the +name of the class to use, and the list of static objects to fixup, are +stored by the compiler in the object file in a place where the GNU +runtime library will find them at runtime). + +As a result, when a file is compiled with the +@option{-fconstant-string-class} option, all the constant string objects +will be instances of the class specified as argument to this option. It +is possible to have multiple compilation units referring to different +constant string classes, neither the compiler nor the linker impose any +restrictions in doing this. + +@c ========================================================================= +@node compatibility_alias +@section compatibility_alias + +The keyword @code{@@compatibility_alias} allows you to define a class name +as equivalent to another class name. For example: + +@smallexample +@@compatibility_alias WOApplication GSWApplication; +@end smallexample + +tells the compiler that each time it encounters @code{WOApplication} as +a class name, it should replace it with @code{GSWApplication} (that is, +@code{WOApplication} is just an alias for @code{GSWApplication}). + +There are some constraints on how this can be used--- + +@itemize @bullet + +@item @code{WOApplication} (the alias) must not be an existing class; + +@item @code{GSWApplication} (the real class) must be an existing class. + +@end itemize + +@c ========================================================================= +@node Exceptions +@section Exceptions + +GNU Objective-C provides exception support built into the language, as +in the following example: + +@smallexample + @@try @{ + @dots{} + @@throw expr; + @dots{} + @} + @@catch (AnObjCClass *exc) @{ + @dots{} + @@throw expr; + @dots{} + @@throw; + @dots{} + @} + @@catch (AnotherClass *exc) @{ + @dots{} + @} + @@catch (id allOthers) @{ + @dots{} + @} + @@finally @{ + @dots{} + @@throw expr; + @dots{} + @} +@end smallexample + +The @code{@@throw} statement may appear anywhere in an Objective-C or +Objective-C++ program; when used inside of a @code{@@catch} block, the +@code{@@throw} may appear without an argument (as shown above), in +which case the object caught by the @code{@@catch} will be rethrown. + +Note that only (pointers to) Objective-C objects may be thrown and +caught using this scheme. When an object is thrown, it will be caught +by the nearest @code{@@catch} clause capable of handling objects of +that type, analogously to how @code{catch} blocks work in C++ and +Java. A @code{@@catch(id @dots{})} clause (as shown above) may also +be provided to catch any and all Objective-C exceptions not caught by +previous @code{@@catch} clauses (if any). + +The @code{@@finally} clause, if present, will be executed upon exit +from the immediately preceding @code{@@try @dots{} @@catch} section. +This will happen regardless of whether any exceptions are thrown, +caught or rethrown inside the @code{@@try @dots{} @@catch} section, +analogously to the behavior of the @code{finally} clause in Java. + +There are several caveats to using the new exception mechanism: + +@itemize @bullet +@item +The @option{-fobjc-exceptions} command line option must be used when +compiling Objective-C files that use exceptions. + +@item +With the GNU runtime, exceptions are always implemented as ``native'' +exceptions and it is recommended that the @option{-fexceptions} and +@option{-shared-libgcc} options are used when linking. + +@item +With the NeXT runtime, although currently designed to be binary +compatible with @code{NS_HANDLER}-style idioms provided by the +@code{NSException} class, the new exceptions can only be used on Mac +OS X 10.3 (Panther) and later systems, due to additional functionality +needed in the NeXT Objective-C runtime. + +@item +As mentioned above, the new exceptions do not support handling +types other than Objective-C objects. Furthermore, when used from +Objective-C++, the Objective-C exception model does not interoperate with C++ +exceptions at this time. This means you cannot @code{@@throw} an exception +from Objective-C and @code{catch} it in C++, or vice versa +(i.e., @code{throw @dots{} @@catch}). +@end itemize + +@c ========================================================================= +@node Synchronization +@section Synchronization + +GNU Objective-C provides support for synchronized blocks: + +@smallexample + @@synchronized (ObjCClass *guard) @{ + @dots{} + @} +@end smallexample + +Upon entering the @code{@@synchronized} block, a thread of execution +shall first check whether a lock has been placed on the corresponding +@code{guard} object by another thread. If it has, the current thread +shall wait until the other thread relinquishes its lock. Once +@code{guard} becomes available, the current thread will place its own +lock on it, execute the code contained in the @code{@@synchronized} +block, and finally relinquish the lock (thereby making @code{guard} +available to other threads). + +Unlike Java, Objective-C does not allow for entire methods to be +marked @code{@@synchronized}. Note that throwing exceptions out of +@code{@@synchronized} blocks is allowed, and will cause the guarding +object to be unlocked properly. + +Because of the interactions between synchronization and exception +handling, you can only use @code{@@synchronized} when compiling with +exceptions enabled, that is with the command line option +@option{-fobjc-exceptions}. + + +@c ========================================================================= +@node Fast enumeration +@section Fast enumeration + +@menu +* Using fast enumeration:: +* c99-like fast enumeration syntax:: +* Fast enumeration details:: +* Fast enumeration protocol:: +@end menu + +@c ================================ +@node Using fast enumeration +@subsection Using fast enumeration + +GNU Objective-C provides support for the fast enumeration syntax: + +@smallexample + id array = @dots{}; + id object; + + for (object in array) + @{ + /* Do something with 'object' */ + @} +@end smallexample + +@code{array} needs to be an Objective-C object (usually a collection +object, for example an array, a dictionary or a set) which implements +the ``Fast Enumeration Protocol'' (see below). If you are using a +Foundation library such as GNUstep Base or Apple Cocoa Foundation, all +collection objects in the library implement this protocol and can be +used in this way. + +The code above would iterate over all objects in @code{array}. For +each of them, it assigns it to @code{object}, then executes the +@code{Do something with 'object'} statements. + +Here is a fully worked-out example using a Foundation library (which +provides the implementation of @code{NSArray}, @code{NSString} and +@code{NSLog}): + +@smallexample + NSArray *array = [NSArray arrayWithObjects: @@"1", @@"2", @@"3", nil]; + NSString *object; + + for (object in array) + NSLog (@@"Iterating over %@@", object); +@end smallexample + + +@c ================================ +@node c99-like fast enumeration syntax +@subsection c99-like fast enumeration syntax + +A c99-like declaration syntax is also allowed: + +@smallexample + id array = @dots{}; + + for (id object in array) + @{ + /* Do something with 'object' */ + @} +@end smallexample + +this is completely equivalent to: + +@smallexample + id array = @dots{}; + + @{ + id object; + for (object in array) + @{ + /* Do something with 'object' */ + @} + @} +@end smallexample + +but can save some typing. + +Note that the option @option{-std=c99} is not required to allow this +syntax in Objective-C. + +@c ================================ +@node Fast enumeration details +@subsection Fast enumeration details + +Here is a more technical description with the gory details. Consider the code + +@smallexample + for (@var{object expression} in @var{collection expression}) + @{ + @var{statements} + @} +@end smallexample + +here is what happens when you run it: + +@itemize @bullet +@item +@code{@var{collection expression}} is evaluated exactly once and the +result is used as the collection object to iterate over. This means +it is safe to write code such as @code{for (object in [NSDictionary +keyEnumerator]) @dots{}}. + +@item +the iteration is implemented by the compiler by repeatedly getting +batches of objects from the collection object using the fast +enumeration protocol (see below), then iterating over all objects in +the batch. This is faster than a normal enumeration where objects are +retrieved one by one (hence the name ``fast enumeration''). + +@item +if there are no objects in the collection, then +@code{@var{object expression}} is set to @code{nil} and the loop +immediately terminates. + +@item +if there are objects in the collection, then for each object in the +collection (in the order they are returned) @code{@var{object expression}} +is set to the object, then @code{@var{statements}} are executed. + +@item +@code{@var{statements}} can contain @code{break} and @code{continue} +commands, which will abort the iteration or skip to the next loop +iteration as expected. + +@item +when the iteration ends because there are no more objects to iterate +over, @code{@var{object expression}} is set to @code{nil}. This allows +you to determine whether the iteration finished because a @code{break} +command was used (in which case @code{@var{object expression}} will remain +set to the last object that was iterated over) or because it iterated +over all the objects (in which case @code{@var{object expression}} will be +set to @code{nil}). + +@item +@code{@var{statements}} must not make any changes to the collection +object; if they do, it is a hard error and the fast enumeration +terminates by invoking @code{objc_enumerationMutation}, a runtime +function that normally aborts the program but which can be customized +by Foundation libraries via @code{objc_set_mutation_handler} to do +something different, such as raising an exception. + +@end itemize + +@c ================================ +@node Fast enumeration protocol +@subsection Fast enumeration protocol + +If you want your own collection object to be usable with fast +enumeration, you need to have it implement the method + +@smallexample +- (unsigned long) countByEnumeratingWithState: (NSFastEnumerationState *)state + objects: (id *)objects + count: (unsigned long)len; +@end smallexample + +where @code{NSFastEnumerationState} must be defined in your code as follows: + +@smallexample +typedef struct +@{ + unsigned long state; + id *itemsPtr; + unsigned long *mutationsPtr; + unsigned long extra[5]; +@} NSFastEnumerationState; +@end smallexample + +If no @code{NSFastEnumerationState} is defined in your code, the +compiler will automatically replace @code{NSFastEnumerationState *} +with @code{struct __objcFastEnumerationState *}, where that type is +silently defined by the compiler in an identical way. This can be +confusing and we recommend that you define +@code{NSFastEnumerationState} (as shown above) instead. + +The method is called repeatedly during a fast enumeration to retrieve +batches of objects. Each invocation of the method should retrieve the +next batch of objects. + +The return value of the method is the number of objects in the current +batch; this should not exceed @code{len}, which is the maximum size of +a batch as requested by the caller. The batch itself is returned in +the @code{itemsPtr} field of the @code{NSFastEnumerationState} struct. + +To help with returning the objects, the @code{objects} array is a C +array preallocated by the caller (on the stack) of size @code{len}. +In many cases you can put the objects you want to return in that +@code{objects} array, then do @code{itemsPtr = objects}. But you +don't have to; if your collection already has the objects to return in +some form of C array, it could return them from there instead. + +The @code{state} and @code{extra} fields of the +@code{NSFastEnumerationState} structure allows your collection object +to keep track of the state of the enumeration. In a simple array +implementation, @code{state} may keep track of the index of the last +object that was returned, and @code{extra} may be unused. + +The @code{mutationsPtr} field of the @code{NSFastEnumerationState} is +used to keep track of mutations. It should point to a number; before +working on each object, the fast enumeration loop will check that this +number has not changed. If it has, a mutation has happened and the +fast enumeration will abort. So, @code{mutationsPtr} could be set to +point to some sort of version number of your collection, which is +increased by one every time there is a change (for example when an +object is added or removed). Or, if you are content with less strict +mutation checks, it could point to the number of objects in your +collection or some other value that can be checked to perform an +approximate check that the collection has not been mutated. + +Finally, note how we declared the @code{len} argument and the return +value to be of type @code{unsigned long}. They could also be declared +to be of type @code{unsigned int} and everything would still work. + +@c ========================================================================= +@node Messaging with the GNU Objective-C runtime +@section Messaging with the GNU Objective-C runtime + +This section is specific for the GNU Objective-C runtime. If you are +using a different runtime, you can skip it. + +The implementation of messaging in the GNU Objective-C runtime is +designed to be portable, and so is based on standard C. + +Sending a message in the GNU Objective-C runtime is composed of two +separate steps. First, there is a call to the lookup function, +@code{objc_msg_lookup ()} (or, in the case of messages to super, +@code{objc_msg_lookup_super ()}). This runtime function takes as +argument the receiver and the selector of the method to be called; it +returns the @code{IMP}, that is a pointer to the function implementing +the method. The second step of method invocation consists of casting +this pointer function to the appropriate function pointer type, and +calling the function pointed to it with the right arguments. + +For example, when the compiler encounters a method invocation such as +@code{[object init]}, it compiles it into a call to +@code{objc_msg_lookup (object, @@selector(init))} followed by a cast +of the returned value to the appropriate function pointer type, and +then it calls it. + +@menu +* Dynamically registering methods:: +* Forwarding hook:: +@end menu + +@c ========================================================================= +@node Dynamically registering methods +@subsection Dynamically registering methods + +If @code{objc_msg_lookup()} does not find a suitable method +implementation, because the receiver does not implement the required +method, it tries to see if the class can dynamically register the +method. + +To do so, the runtime checks if the class of the receiver implements +the method + +@smallexample ++ (BOOL) resolveInstanceMethod: (SEL)selector; +@end smallexample + +in the case of an instance method, or + +@smallexample ++ (BOOL) resolveClassMethod: (SEL)selector; +@end smallexample + +in the case of a class method. If the class implements it, the +runtime invokes it, passing as argument the selector of the original +method, and if it returns @code{YES}, the runtime tries the lookup +again, which could now succeed if a matching method was added +dynamically by @code{+resolveInstanceMethod:} or +@code{+resolveClassMethod:}. + +This allows classes to dynamically register methods (by adding them to +the class using @code{class_addMethod}) when they are first called. +To do so, a class should implement @code{+resolveInstanceMethod:} (or, +depending on the case, @code{+resolveClassMethod:}) and have it +recognize the selectors of methods that can be registered dynamically +at runtime, register them, and return @code{YES}. It should return +@code{NO} for methods that it does not dynamically registered at +runtime. + +If @code{+resolveInstanceMethod:} (or @code{+resolveClassMethod:}) is +not implemented or returns @code{NO}, the runtime then tries the +forwarding hook. + +Support for @code{+resolveInstanceMethod:} and +@code{resolveClassMethod:} was added to the GNU Objective-C runtime in +GCC version 4.6. + +@c ========================================================================= +@node Forwarding hook +@subsection Forwarding hook + +The GNU Objective-C runtime provides a hook, called +@code{__objc_msg_forward2}, which is called by +@code{objc_msg_lookup()} when it can't find a method implementation in +the runtime tables and after calling @code{+resolveInstanceMethod:} +and @code{+resolveClassMethod:} has been attempted and did not succeed +in dynamically registering the method. + +To configure the hook, you set the global variable +@code{__objc_msg_foward2} to a function with the same argument and +return types of @code{objc_msg_lookup()}. When +@code{objc_msg_lookup()} can not find a method implementation, it +invokes the hook function you provided to get a method implementation +to return. So, in practice @code{__objc_msg_forward2} allows you to +extend @code{objc_msg_lookup()} by adding some custom code that is +called to do a further lookup when no standard method implementation +can be found using the normal lookup. + +This hook is generally reserved for ``Foundation'' libraries such as +GNUstep Base, which use it to implement their high-level method +forwarding API, typically based around the @code{forwardInvocation:} +method. So, unless you are implementing your own ``Foundation'' +library, you should not set this hook. + +In a typical forwarding implementation, the @code{__objc_msg_forward2} +hook function determines the argument and return type of the method +that is being looked up, and then creates a function that takes these +arguments and has that return type, and returns it to the caller. +Creating this function is non-trivial and is typically performed using +a dedicated library such as @code{libffi}. + +The forwarding method implementation thus created is returned by +@code{objc_msg_lookup()} and is executed as if it was a normal method +implementation. When the forwarding method implementation is called, +it is usually expected to pack all arguments into some sort of object +(typically, an @code{NSInvocation} in a ``Foundation'' library), and +hand it over to the programmer (@code{forwardInvocation:}) who is then +allowed to manipulate the method invocation using a high-level API +provided by the ``Foundation'' library. For example, the programmer +may want to examine the method invocation arguments and name and +potentially change them before forwarding the method invocation to one +or more local objects (@code{performInvocation:}) or even to remote +objects (by using Distributed Objects or some other mechanism). When +all this completes, the return value is passed back and must be +returned correctly to the original caller. + +Note that the GNU Objective-C runtime currently provides no support +for method forwarding or method invocations other than the +@code{__objc_msg_forward2} hook. + +If the forwarding hook does not exist or returns @code{NULL}, the +runtime currently attempts forwarding using an older, deprecated API, +and if that fails, it aborts the program. In future versions of the +GNU Objective-C runtime, the runtime will immediately abort. |