| @c Copyright (C) 1988-2021 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. |
| |
| Starting with GCC 4.7.0, the traditional GNU runtime API is no longer |
| available. |
| |
| @c ========================================================================= |
| @node Executing code before main |
| @section @code{+load}: Executing Code before @code{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 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 .60 .40 |
| @headitem 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 depends 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 |
| @headitem 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 |
| @headitem 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 @code{@@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 |
| @{ |
| if (self == objc_lookUpClass ("WeakPointer")) |
| 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 @code{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 cannot 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_forward2} to a function with the same argument and |
| return types of @code{objc_msg_lookup()}. When |
| @code{objc_msg_lookup()} cannot 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. |