12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211 |
- @c Copyright (C) 1988-2015 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 .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 @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 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_forward2} 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.
|