1*8feb0f0bSmrg@c Copyright (C) 1988-2020 Free Software Foundation, Inc. 21debfc3dSmrg@c This is part of the GCC manual. 31debfc3dSmrg@c For copying conditions, see the file gcc.texi. 41debfc3dSmrg 51debfc3dSmrg@node Objective-C 61debfc3dSmrg@comment node-name, next, previous, up 71debfc3dSmrg 81debfc3dSmrg@chapter GNU Objective-C Features 91debfc3dSmrg 101debfc3dSmrgThis document is meant to describe some of the GNU Objective-C 111debfc3dSmrgfeatures. It is not intended to teach you Objective-C. There are 121debfc3dSmrgseveral resources on the Internet that present the language. 131debfc3dSmrg 141debfc3dSmrg@menu 151debfc3dSmrg* GNU Objective-C runtime API:: 161debfc3dSmrg* Executing code before main:: 171debfc3dSmrg* Type encoding:: 181debfc3dSmrg* Garbage Collection:: 191debfc3dSmrg* Constant string objects:: 201debfc3dSmrg* compatibility_alias:: 211debfc3dSmrg* Exceptions:: 221debfc3dSmrg* Synchronization:: 231debfc3dSmrg* Fast enumeration:: 241debfc3dSmrg* Messaging with the GNU Objective-C runtime:: 251debfc3dSmrg@end menu 261debfc3dSmrg 271debfc3dSmrg@c ========================================================================= 281debfc3dSmrg@node GNU Objective-C runtime API 291debfc3dSmrg@section GNU Objective-C Runtime API 301debfc3dSmrg 311debfc3dSmrgThis section is specific for the GNU Objective-C runtime. If you are 321debfc3dSmrgusing a different runtime, you can skip it. 331debfc3dSmrg 341debfc3dSmrgThe GNU Objective-C runtime provides an API that allows you to 351debfc3dSmrginteract with the Objective-C runtime system, querying the live 361debfc3dSmrgruntime structures and even manipulating them. This allows you for 371debfc3dSmrgexample to inspect and navigate classes, methods and protocols; to 381debfc3dSmrgdefine new classes or new methods, and even to modify existing classes 391debfc3dSmrgor protocols. 401debfc3dSmrg 411debfc3dSmrgIf you are using a ``Foundation'' library such as GNUstep-Base, this 421debfc3dSmrglibrary will provide you with a rich set of functionality to do most 431debfc3dSmrgof the inspection tasks, and you probably will only need direct access 441debfc3dSmrgto the GNU Objective-C runtime API to define new classes or methods. 451debfc3dSmrg 461debfc3dSmrg@menu 471debfc3dSmrg* Modern GNU Objective-C runtime API:: 481debfc3dSmrg* Traditional GNU Objective-C runtime API:: 491debfc3dSmrg@end menu 501debfc3dSmrg 511debfc3dSmrg@c ========================================================================= 521debfc3dSmrg@node Modern GNU Objective-C runtime API 531debfc3dSmrg@subsection Modern GNU Objective-C Runtime API 541debfc3dSmrg 551debfc3dSmrgThe GNU Objective-C runtime provides an API which is similar to the 561debfc3dSmrgone provided by the ``Objective-C 2.0'' Apple/NeXT Objective-C 571debfc3dSmrgruntime. The API is documented in the public header files of the GNU 581debfc3dSmrgObjective-C runtime: 591debfc3dSmrg 601debfc3dSmrg@itemize @bullet 611debfc3dSmrg 621debfc3dSmrg@item 631debfc3dSmrg@file{objc/objc.h}: this is the basic Objective-C header file, 641debfc3dSmrgdefining the basic Objective-C types such as @code{id}, @code{Class} 651debfc3dSmrgand @code{BOOL}. You have to include this header to do almost 661debfc3dSmrganything with Objective-C. 671debfc3dSmrg 681debfc3dSmrg@item 691debfc3dSmrg@file{objc/runtime.h}: this header declares most of the public runtime 701debfc3dSmrgAPI functions allowing you to inspect and manipulate the Objective-C 711debfc3dSmrgruntime data structures. These functions are fairly standardized 721debfc3dSmrgacross Objective-C runtimes and are almost identical to the Apple/NeXT 731debfc3dSmrgObjective-C runtime ones. It does not declare functions in some 741debfc3dSmrgspecialized areas (constructing and forwarding message invocations, 751debfc3dSmrgthreading) which are in the other headers below. You have to include 761debfc3dSmrg@file{objc/objc.h} and @file{objc/runtime.h} to use any of the 771debfc3dSmrgfunctions, such as @code{class_getName()}, declared in 781debfc3dSmrg@file{objc/runtime.h}. 791debfc3dSmrg 801debfc3dSmrg@item 811debfc3dSmrg@file{objc/message.h}: this header declares public functions used to 821debfc3dSmrgconstruct, deconstruct and forward message invocations. Because 831debfc3dSmrgmessaging is done in quite a different way on different runtimes, 841debfc3dSmrgfunctions in this header are specific to the GNU Objective-C runtime 851debfc3dSmrgimplementation. 861debfc3dSmrg 871debfc3dSmrg@item 881debfc3dSmrg@file{objc/objc-exception.h}: this header declares some public 891debfc3dSmrgfunctions related to Objective-C exceptions. For example functions in 901debfc3dSmrgthis header allow you to throw an Objective-C exception from plain 911debfc3dSmrgC/C++ code. 921debfc3dSmrg 931debfc3dSmrg@item 941debfc3dSmrg@file{objc/objc-sync.h}: this header declares some public functions 951debfc3dSmrgrelated to the Objective-C @code{@@synchronized()} syntax, allowing 961debfc3dSmrgyou to emulate an Objective-C @code{@@synchronized()} block in plain 971debfc3dSmrgC/C++ code. 981debfc3dSmrg 991debfc3dSmrg@item 1001debfc3dSmrg@file{objc/thr.h}: this header declares a public runtime API threading 1011debfc3dSmrglayer that is only provided by the GNU Objective-C runtime. It 1021debfc3dSmrgdeclares functions such as @code{objc_mutex_lock()}, which provide a 1031debfc3dSmrgplatform-independent set of threading functions. 1041debfc3dSmrg 1051debfc3dSmrg@end itemize 1061debfc3dSmrg 1071debfc3dSmrgThe header files contain detailed documentation for each function in 1081debfc3dSmrgthe GNU Objective-C runtime API. 1091debfc3dSmrg 1101debfc3dSmrg@c ========================================================================= 1111debfc3dSmrg@node Traditional GNU Objective-C runtime API 1121debfc3dSmrg@subsection Traditional GNU Objective-C Runtime API 1131debfc3dSmrg 1141debfc3dSmrgThe GNU Objective-C runtime used to provide a different API, which we 1151debfc3dSmrgcall the ``traditional'' GNU Objective-C runtime API. Functions 1161debfc3dSmrgbelonging to this API are easy to recognize because they use a 1171debfc3dSmrgdifferent naming convention, such as @code{class_get_super_class()} 1181debfc3dSmrg(traditional API) instead of @code{class_getSuperclass()} (modern 1191debfc3dSmrgAPI). Software using this API includes the file 1201debfc3dSmrg@file{objc/objc-api.h} where it is declared. 1211debfc3dSmrg 1221debfc3dSmrgStarting with GCC 4.7.0, the traditional GNU runtime API is no longer 1231debfc3dSmrgavailable. 1241debfc3dSmrg 1251debfc3dSmrg@c ========================================================================= 1261debfc3dSmrg@node Executing code before main 1271debfc3dSmrg@section @code{+load}: Executing Code before @code{main} 1281debfc3dSmrg 1291debfc3dSmrgThis section is specific for the GNU Objective-C runtime. If you are 1301debfc3dSmrgusing a different runtime, you can skip it. 1311debfc3dSmrg 1321debfc3dSmrgThe GNU Objective-C runtime provides a way that allows you to execute 1331debfc3dSmrgcode before the execution of the program enters the @code{main} 1341debfc3dSmrgfunction. The code is executed on a per-class and a per-category basis, 1351debfc3dSmrgthrough a special class method @code{+load}. 1361debfc3dSmrg 1371debfc3dSmrgThis facility is very useful if you want to initialize global variables 1381debfc3dSmrgwhich can be accessed by the program directly, without sending a message 1391debfc3dSmrgto the class first. The usual way to initialize global variables, in the 1401debfc3dSmrg@code{+initialize} method, might not be useful because 1411debfc3dSmrg@code{+initialize} is only called when the first message is sent to a 1421debfc3dSmrgclass object, which in some cases could be too late. 1431debfc3dSmrg 1441debfc3dSmrgSuppose for example you have a @code{FileStream} class that declares 1451debfc3dSmrg@code{Stdin}, @code{Stdout} and @code{Stderr} as global variables, like 1461debfc3dSmrgbelow: 1471debfc3dSmrg 1481debfc3dSmrg@smallexample 1491debfc3dSmrg 1501debfc3dSmrgFileStream *Stdin = nil; 1511debfc3dSmrgFileStream *Stdout = nil; 1521debfc3dSmrgFileStream *Stderr = nil; 1531debfc3dSmrg 1541debfc3dSmrg@@implementation FileStream 1551debfc3dSmrg 1561debfc3dSmrg+ (void)initialize 1571debfc3dSmrg@{ 1581debfc3dSmrg Stdin = [[FileStream new] initWithFd:0]; 1591debfc3dSmrg Stdout = [[FileStream new] initWithFd:1]; 1601debfc3dSmrg Stderr = [[FileStream new] initWithFd:2]; 1611debfc3dSmrg@} 1621debfc3dSmrg 1631debfc3dSmrg/* @r{Other methods here} */ 1641debfc3dSmrg@@end 1651debfc3dSmrg 1661debfc3dSmrg@end smallexample 1671debfc3dSmrg 1681debfc3dSmrgIn this example, the initialization of @code{Stdin}, @code{Stdout} and 1691debfc3dSmrg@code{Stderr} in @code{+initialize} occurs too late. The programmer can 1701debfc3dSmrgsend a message to one of these objects before the variables are actually 1711debfc3dSmrginitialized, thus sending messages to the @code{nil} object. The 1721debfc3dSmrg@code{+initialize} method which actually initializes the global 1731debfc3dSmrgvariables is not invoked until the first message is sent to the class 1741debfc3dSmrgobject. The solution would require these variables to be initialized 1751debfc3dSmrgjust before entering @code{main}. 1761debfc3dSmrg 1771debfc3dSmrgThe correct solution of the above problem is to use the @code{+load} 1781debfc3dSmrgmethod instead of @code{+initialize}: 1791debfc3dSmrg 1801debfc3dSmrg@smallexample 1811debfc3dSmrg 1821debfc3dSmrg@@implementation FileStream 1831debfc3dSmrg 1841debfc3dSmrg+ (void)load 1851debfc3dSmrg@{ 1861debfc3dSmrg Stdin = [[FileStream new] initWithFd:0]; 1871debfc3dSmrg Stdout = [[FileStream new] initWithFd:1]; 1881debfc3dSmrg Stderr = [[FileStream new] initWithFd:2]; 1891debfc3dSmrg@} 1901debfc3dSmrg 1911debfc3dSmrg/* @r{Other methods here} */ 1921debfc3dSmrg@@end 1931debfc3dSmrg 1941debfc3dSmrg@end smallexample 1951debfc3dSmrg 1961debfc3dSmrgThe @code{+load} is a method that is not overridden by categories. If a 1971debfc3dSmrgclass and a category of it both implement @code{+load}, both methods are 1981debfc3dSmrginvoked. This allows some additional initializations to be performed in 1991debfc3dSmrga category. 2001debfc3dSmrg 2011debfc3dSmrgThis mechanism is not intended to be a replacement for @code{+initialize}. 2021debfc3dSmrgYou should be aware of its limitations when you decide to use it 2031debfc3dSmrginstead of @code{+initialize}. 2041debfc3dSmrg 2051debfc3dSmrg@menu 2061debfc3dSmrg* What you can and what you cannot do in +load:: 2071debfc3dSmrg@end menu 2081debfc3dSmrg 2091debfc3dSmrg 2101debfc3dSmrg@node What you can and what you cannot do in +load 2111debfc3dSmrg@subsection What You Can and Cannot Do in @code{+load} 2121debfc3dSmrg 2131debfc3dSmrg@code{+load} is to be used only as a last resort. Because it is 2141debfc3dSmrgexecuted very early, most of the Objective-C runtime machinery will 2151debfc3dSmrgnot be ready when @code{+load} is executed; hence @code{+load} works 2161debfc3dSmrgbest for executing C code that is independent on the Objective-C 2171debfc3dSmrgruntime. 2181debfc3dSmrg 2191debfc3dSmrgThe @code{+load} implementation in the GNU runtime guarantees you the 2201debfc3dSmrgfollowing things: 2211debfc3dSmrg 2221debfc3dSmrg@itemize @bullet 2231debfc3dSmrg 2241debfc3dSmrg@item 2251debfc3dSmrgyou can write whatever C code you like; 2261debfc3dSmrg 2271debfc3dSmrg@item 2281debfc3dSmrgyou can allocate and send messages to objects whose class is implemented 2291debfc3dSmrgin the same file; 2301debfc3dSmrg 2311debfc3dSmrg@item 2321debfc3dSmrgthe @code{+load} implementation of all super classes of a class are 2331debfc3dSmrgexecuted before the @code{+load} of that class is executed; 2341debfc3dSmrg 2351debfc3dSmrg@item 2361debfc3dSmrgthe @code{+load} implementation of a class is executed before the 2371debfc3dSmrg@code{+load} implementation of any category. 2381debfc3dSmrg 2391debfc3dSmrg@end itemize 2401debfc3dSmrg 2411debfc3dSmrgIn particular, the following things, even if they can work in a 2421debfc3dSmrgparticular case, are not guaranteed: 2431debfc3dSmrg 2441debfc3dSmrg@itemize @bullet 2451debfc3dSmrg 2461debfc3dSmrg@item 2471debfc3dSmrgallocation of or sending messages to arbitrary objects; 2481debfc3dSmrg 2491debfc3dSmrg@item 2501debfc3dSmrgallocation of or sending messages to objects whose classes have a 2511debfc3dSmrgcategory implemented in the same file; 2521debfc3dSmrg 2531debfc3dSmrg@item 2541debfc3dSmrgsending messages to Objective-C constant strings (@code{@@"this is a 2551debfc3dSmrgconstant string"}); 2561debfc3dSmrg 2571debfc3dSmrg@end itemize 2581debfc3dSmrg 2591debfc3dSmrgYou should make no assumptions about receiving @code{+load} in sibling 2601debfc3dSmrgclasses when you write @code{+load} of a class. The order in which 2611debfc3dSmrgsibling classes receive @code{+load} is not guaranteed. 2621debfc3dSmrg 2631debfc3dSmrgThe order in which @code{+load} and @code{+initialize} are called could 2641debfc3dSmrgbe problematic if this matters. If you don't allocate objects inside 2651debfc3dSmrg@code{+load}, it is guaranteed that @code{+load} is called before 2661debfc3dSmrg@code{+initialize}. If you create an object inside @code{+load} the 2671debfc3dSmrg@code{+initialize} method of object's class is invoked even if 2681debfc3dSmrg@code{+load} was not invoked. Note if you explicitly call @code{+load} 2691debfc3dSmrgon a class, @code{+initialize} will be called first. To avoid possible 2701debfc3dSmrgproblems try to implement only one of these methods. 2711debfc3dSmrg 2721debfc3dSmrgThe @code{+load} method is also invoked when a bundle is dynamically 2731debfc3dSmrgloaded into your running program. This happens automatically without any 2741debfc3dSmrgintervening operation from you. When you write bundles and you need to 2751debfc3dSmrgwrite @code{+load} you can safely create and send messages to objects whose 2761debfc3dSmrgclasses already exist in the running program. The same restrictions as 2771debfc3dSmrgabove apply to classes defined in bundle. 2781debfc3dSmrg 2791debfc3dSmrg 2801debfc3dSmrg 2811debfc3dSmrg@node Type encoding 2821debfc3dSmrg@section Type Encoding 2831debfc3dSmrg 2841debfc3dSmrgThis is an advanced section. Type encodings are used extensively by 2851debfc3dSmrgthe compiler and by the runtime, but you generally do not need to know 2861debfc3dSmrgabout them to use Objective-C. 2871debfc3dSmrg 2881debfc3dSmrgThe Objective-C compiler generates type encodings for all the types. 2891debfc3dSmrgThese type encodings are used at runtime to find out information about 2901debfc3dSmrgselectors and methods and about objects and classes. 2911debfc3dSmrg 2921debfc3dSmrgThe types are encoded in the following way: 2931debfc3dSmrg 2941debfc3dSmrg@c @sp 1 2951debfc3dSmrg 2961debfc3dSmrg@multitable @columnfractions .25 .75 2971debfc3dSmrg@item @code{_Bool} 2981debfc3dSmrg@tab @code{B} 2991debfc3dSmrg@item @code{char} 3001debfc3dSmrg@tab @code{c} 3011debfc3dSmrg@item @code{unsigned char} 3021debfc3dSmrg@tab @code{C} 3031debfc3dSmrg@item @code{short} 3041debfc3dSmrg@tab @code{s} 3051debfc3dSmrg@item @code{unsigned short} 3061debfc3dSmrg@tab @code{S} 3071debfc3dSmrg@item @code{int} 3081debfc3dSmrg@tab @code{i} 3091debfc3dSmrg@item @code{unsigned int} 3101debfc3dSmrg@tab @code{I} 3111debfc3dSmrg@item @code{long} 3121debfc3dSmrg@tab @code{l} 3131debfc3dSmrg@item @code{unsigned long} 3141debfc3dSmrg@tab @code{L} 3151debfc3dSmrg@item @code{long long} 3161debfc3dSmrg@tab @code{q} 3171debfc3dSmrg@item @code{unsigned long long} 3181debfc3dSmrg@tab @code{Q} 3191debfc3dSmrg@item @code{float} 3201debfc3dSmrg@tab @code{f} 3211debfc3dSmrg@item @code{double} 3221debfc3dSmrg@tab @code{d} 3231debfc3dSmrg@item @code{long double} 3241debfc3dSmrg@tab @code{D} 3251debfc3dSmrg@item @code{void} 3261debfc3dSmrg@tab @code{v} 3271debfc3dSmrg@item @code{id} 3281debfc3dSmrg@tab @code{@@} 3291debfc3dSmrg@item @code{Class} 3301debfc3dSmrg@tab @code{#} 3311debfc3dSmrg@item @code{SEL} 3321debfc3dSmrg@tab @code{:} 3331debfc3dSmrg@item @code{char*} 3341debfc3dSmrg@tab @code{*} 3351debfc3dSmrg@item @code{enum} 3361debfc3dSmrg@tab an @code{enum} is encoded exactly as the integer type that the compiler uses for it, which depends on the enumeration 3371debfc3dSmrgvalues. Often the compiler users @code{unsigned int}, which is then encoded as @code{I}. 3381debfc3dSmrg@item unknown type 3391debfc3dSmrg@tab @code{?} 3401debfc3dSmrg@item Complex types 3411debfc3dSmrg@tab @code{j} followed by the inner type. For example @code{_Complex double} is encoded as "jd". 3421debfc3dSmrg@item bit-fields 3431debfc3dSmrg@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) 3441debfc3dSmrg@end multitable 3451debfc3dSmrg 3461debfc3dSmrg@c @sp 1 3471debfc3dSmrg 3481debfc3dSmrgThe encoding of bit-fields has changed to allow bit-fields to be 3491debfc3dSmrgproperly handled by the runtime functions that compute sizes and 3501debfc3dSmrgalignments of types that contain bit-fields. The previous encoding 3511debfc3dSmrgcontained only the size of the bit-field. Using only this information 3521debfc3dSmrgit is not possible to reliably compute the size occupied by the 3531debfc3dSmrgbit-field. This is very important in the presence of the Boehm's 3541debfc3dSmrggarbage collector because the objects are allocated using the typed 3551debfc3dSmrgmemory facility available in this collector. The typed memory 3561debfc3dSmrgallocation requires information about where the pointers are located 3571debfc3dSmrginside the object. 3581debfc3dSmrg 3591debfc3dSmrgThe position in the bit-field is the position, counting in bits, of the 3601debfc3dSmrgbit closest to the beginning of the structure. 3611debfc3dSmrg 3621debfc3dSmrgThe non-atomic types are encoded as follows: 3631debfc3dSmrg 3641debfc3dSmrg@c @sp 1 3651debfc3dSmrg 3661debfc3dSmrg@multitable @columnfractions .2 .8 3671debfc3dSmrg@item pointers 3681debfc3dSmrg@tab @samp{^} followed by the pointed type. 3691debfc3dSmrg@item arrays 3701debfc3dSmrg@tab @samp{[} followed by the number of elements in the array followed by the type of the elements followed by @samp{]} 3711debfc3dSmrg@item structures 3721debfc3dSmrg@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{@}} 3731debfc3dSmrg@item unions 3741debfc3dSmrg@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{)} 3751debfc3dSmrg@item vectors 3761debfc3dSmrg@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{]} 3771debfc3dSmrg@end multitable 3781debfc3dSmrg 3791debfc3dSmrgHere are some types and their encodings, as they are generated by the 3801debfc3dSmrgcompiler on an i386 machine: 3811debfc3dSmrg 3821debfc3dSmrg@sp 1 3831debfc3dSmrg 3841debfc3dSmrg@multitable @columnfractions .60 .40 3851debfc3dSmrg@item Objective-C type 3861debfc3dSmrg@tab Compiler encoding 3871debfc3dSmrg@item 3881debfc3dSmrg@smallexample 3891debfc3dSmrgint a[10]; 3901debfc3dSmrg@end smallexample 3911debfc3dSmrg@tab @code{[10i]} 3921debfc3dSmrg@item 3931debfc3dSmrg@smallexample 3941debfc3dSmrgstruct @{ 3951debfc3dSmrg int i; 3961debfc3dSmrg float f[3]; 3971debfc3dSmrg int a:3; 3981debfc3dSmrg int b:2; 3991debfc3dSmrg char c; 4001debfc3dSmrg@} 4011debfc3dSmrg@end smallexample 4021debfc3dSmrg@tab @code{@{?=i[3f]b128i3b131i2c@}} 4031debfc3dSmrg@item 4041debfc3dSmrg@smallexample 4051debfc3dSmrgint a __attribute__ ((vector_size (16))); 4061debfc3dSmrg@end smallexample 4071debfc3dSmrg@tab @code{![16,16i]} (alignment depends on the machine) 4081debfc3dSmrg@end multitable 4091debfc3dSmrg 4101debfc3dSmrg@sp 1 4111debfc3dSmrg 4121debfc3dSmrgIn addition to the types the compiler also encodes the type 4131debfc3dSmrgspecifiers. The table below describes the encoding of the current 4141debfc3dSmrgObjective-C type specifiers: 4151debfc3dSmrg 4161debfc3dSmrg@sp 1 4171debfc3dSmrg 4181debfc3dSmrg@multitable @columnfractions .25 .75 4191debfc3dSmrg@item Specifier 4201debfc3dSmrg@tab Encoding 4211debfc3dSmrg@item @code{const} 4221debfc3dSmrg@tab @code{r} 4231debfc3dSmrg@item @code{in} 4241debfc3dSmrg@tab @code{n} 4251debfc3dSmrg@item @code{inout} 4261debfc3dSmrg@tab @code{N} 4271debfc3dSmrg@item @code{out} 4281debfc3dSmrg@tab @code{o} 4291debfc3dSmrg@item @code{bycopy} 4301debfc3dSmrg@tab @code{O} 4311debfc3dSmrg@item @code{byref} 4321debfc3dSmrg@tab @code{R} 4331debfc3dSmrg@item @code{oneway} 4341debfc3dSmrg@tab @code{V} 4351debfc3dSmrg@end multitable 4361debfc3dSmrg 4371debfc3dSmrg@sp 1 4381debfc3dSmrg 4391debfc3dSmrgThe type specifiers are encoded just before the type. Unlike types 4401debfc3dSmrghowever, the type specifiers are only encoded when they appear in method 4411debfc3dSmrgargument types. 4421debfc3dSmrg 4431debfc3dSmrgNote how @code{const} interacts with pointers: 4441debfc3dSmrg 4451debfc3dSmrg@sp 1 4461debfc3dSmrg 4471debfc3dSmrg@multitable @columnfractions .25 .75 4481debfc3dSmrg@item Objective-C type 4491debfc3dSmrg@tab Compiler encoding 4501debfc3dSmrg@item 4511debfc3dSmrg@smallexample 4521debfc3dSmrgconst int 4531debfc3dSmrg@end smallexample 4541debfc3dSmrg@tab @code{ri} 4551debfc3dSmrg@item 4561debfc3dSmrg@smallexample 4571debfc3dSmrgconst int* 4581debfc3dSmrg@end smallexample 4591debfc3dSmrg@tab @code{^ri} 4601debfc3dSmrg@item 4611debfc3dSmrg@smallexample 4621debfc3dSmrgint *const 4631debfc3dSmrg@end smallexample 4641debfc3dSmrg@tab @code{r^i} 4651debfc3dSmrg@end multitable 4661debfc3dSmrg 4671debfc3dSmrg@sp 1 4681debfc3dSmrg 4691debfc3dSmrg@code{const int*} is a pointer to a @code{const int}, and so is 4701debfc3dSmrgencoded as @code{^ri}. @code{int* const}, instead, is a @code{const} 4711debfc3dSmrgpointer to an @code{int}, and so is encoded as @code{r^i}. 4721debfc3dSmrg 4731debfc3dSmrgFinally, there is a complication when encoding @code{const char *} 4741debfc3dSmrgversus @code{char * const}. Because @code{char *} is encoded as 4751debfc3dSmrg@code{*} and not as @code{^c}, there is no way to express the fact 4761debfc3dSmrgthat @code{r} applies to the pointer or to the pointee. 4771debfc3dSmrg 4781debfc3dSmrgHence, it is assumed as a convention that @code{r*} means @code{const 4791debfc3dSmrgchar *} (since it is what is most often meant), and there is no way to 4801debfc3dSmrgencode @code{char *const}. @code{char *const} would simply be encoded 4811debfc3dSmrgas @code{*}, and the @code{const} is lost. 4821debfc3dSmrg 4831debfc3dSmrg@menu 4841debfc3dSmrg* Legacy type encoding:: 4851debfc3dSmrg* @@encode:: 4861debfc3dSmrg* Method signatures:: 4871debfc3dSmrg@end menu 4881debfc3dSmrg 4891debfc3dSmrg@node Legacy type encoding 4901debfc3dSmrg@subsection Legacy Type Encoding 4911debfc3dSmrg 4921debfc3dSmrgUnfortunately, historically GCC used to have a number of bugs in its 4931debfc3dSmrgencoding code. The NeXT runtime expects GCC to emit type encodings in 4941debfc3dSmrgthis historical format (compatible with GCC-3.3), so when using the 4951debfc3dSmrgNeXT runtime, GCC will introduce on purpose a number of incorrect 4961debfc3dSmrgencodings: 4971debfc3dSmrg 4981debfc3dSmrg@itemize @bullet 4991debfc3dSmrg 5001debfc3dSmrg@item 5011debfc3dSmrgthe read-only qualifier of the pointee gets emitted before the '^'. 5021debfc3dSmrgThe read-only qualifier of the pointer itself gets ignored, unless it 5031debfc3dSmrgis a typedef. Also, the 'r' is only emitted for the outermost type. 5041debfc3dSmrg 5051debfc3dSmrg@item 5061debfc3dSmrg32-bit longs are encoded as 'l' or 'L', but not always. For typedefs, 5071debfc3dSmrgthe compiler uses 'i' or 'I' instead if encoding a struct field or a 5081debfc3dSmrgpointer. 5091debfc3dSmrg 5101debfc3dSmrg@item 5111debfc3dSmrg@code{enum}s are always encoded as 'i' (int) even if they are actually 5121debfc3dSmrgunsigned or long. 5131debfc3dSmrg 5141debfc3dSmrg@end itemize 5151debfc3dSmrg 5161debfc3dSmrgIn addition to that, the NeXT runtime uses a different encoding for 5171debfc3dSmrgbitfields. It encodes them as @code{b} followed by the size, without 5181debfc3dSmrga bit offset or the underlying field type. 5191debfc3dSmrg 5201debfc3dSmrg@node @@encode 5211debfc3dSmrg@subsection @code{@@encode} 5221debfc3dSmrg 5231debfc3dSmrgGNU Objective-C supports the @code{@@encode} syntax that allows you to 5241debfc3dSmrgcreate a type encoding from a C/Objective-C type. For example, 5251debfc3dSmrg@code{@@encode(int)} is compiled by the compiler into @code{"i"}. 5261debfc3dSmrg 5271debfc3dSmrg@code{@@encode} does not support type qualifiers other than 5281debfc3dSmrg@code{const}. For example, @code{@@encode(const char*)} is valid and 5291debfc3dSmrgis compiled into @code{"r*"}, while @code{@@encode(bycopy char *)} is 5301debfc3dSmrginvalid and will cause a compilation error. 5311debfc3dSmrg 5321debfc3dSmrg@node Method signatures 5331debfc3dSmrg@subsection Method Signatures 5341debfc3dSmrg 5351debfc3dSmrgThis section documents the encoding of method types, which is rarely 5361debfc3dSmrgneeded to use Objective-C. You should skip it at a first reading; the 5371debfc3dSmrgruntime provides functions that will work on methods and can walk 5381debfc3dSmrgthrough the list of parameters and interpret them for you. These 5391debfc3dSmrgfunctions are part of the public ``API'' and are the preferred way to 5401debfc3dSmrginteract with method signatures from user code. 5411debfc3dSmrg 5421debfc3dSmrgBut if you need to debug a problem with method signatures and need to 5431debfc3dSmrgknow how they are implemented (i.e., the ``ABI''), read on. 5441debfc3dSmrg 5451debfc3dSmrgMethods have their ``signature'' encoded and made available to the 5461debfc3dSmrgruntime. The ``signature'' encodes all the information required to 5471debfc3dSmrgdynamically build invocations of the method at runtime: return type 5481debfc3dSmrgand arguments. 5491debfc3dSmrg 5501debfc3dSmrgThe ``signature'' is a null-terminated string, composed of the following: 5511debfc3dSmrg 5521debfc3dSmrg@itemize @bullet 5531debfc3dSmrg 5541debfc3dSmrg@item 5551debfc3dSmrgThe return type, including type qualifiers. For example, a method 5561debfc3dSmrgreturning @code{int} would have @code{i} here. 5571debfc3dSmrg 5581debfc3dSmrg@item 5591debfc3dSmrgThe total size (in bytes) required to pass all the parameters. This 5601debfc3dSmrgincludes the two hidden parameters (the object @code{self} and the 5611debfc3dSmrgmethod selector @code{_cmd}). 5621debfc3dSmrg 5631debfc3dSmrg@item 5641debfc3dSmrgEach argument, with the type encoding, followed by the offset (in 5651debfc3dSmrgbytes) of the argument in the list of parameters. 5661debfc3dSmrg 5671debfc3dSmrg@end itemize 5681debfc3dSmrg 5691debfc3dSmrgFor example, a method with no arguments and returning @code{int} would 5701debfc3dSmrghave the signature @code{i8@@0:4} if the size of a pointer is 4. The 5711debfc3dSmrgsignature is interpreted as follows: the @code{i} is the return type 5721debfc3dSmrg(an @code{int}), the @code{8} is the total size of the parameters in 5731debfc3dSmrgbytes (two pointers each of size 4), the @code{@@0} is the first 5741debfc3dSmrgparameter (an object at byte offset @code{0}) and @code{:4} is the 5751debfc3dSmrgsecond parameter (a @code{SEL} at byte offset @code{4}). 5761debfc3dSmrg 5771debfc3dSmrgYou can easily find more examples by running the ``strings'' program 5781debfc3dSmrgon an Objective-C object file compiled by GCC. You'll see a lot of 5791debfc3dSmrgstrings that look very much like @code{i8@@0:4}. They are signatures 5801debfc3dSmrgof Objective-C methods. 5811debfc3dSmrg 5821debfc3dSmrg 5831debfc3dSmrg@node Garbage Collection 5841debfc3dSmrg@section Garbage Collection 5851debfc3dSmrg 5861debfc3dSmrgThis section is specific for the GNU Objective-C runtime. If you are 5871debfc3dSmrgusing a different runtime, you can skip it. 5881debfc3dSmrg 5891debfc3dSmrgSupport for garbage collection with the GNU runtime has been added by 5901debfc3dSmrgusing a powerful conservative garbage collector, known as the 5911debfc3dSmrgBoehm-Demers-Weiser conservative garbage collector. 5921debfc3dSmrg 5931debfc3dSmrgTo enable the support for it you have to configure the compiler using 5941debfc3dSmrgan additional argument, @w{@option{--enable-objc-gc}}. This will 5951debfc3dSmrgbuild the boehm-gc library, and build an additional runtime library 5961debfc3dSmrgwhich has several enhancements to support the garbage collector. The 5971debfc3dSmrgnew library has a new name, @file{libobjc_gc.a} to not conflict with 5981debfc3dSmrgthe non-garbage-collected library. 5991debfc3dSmrg 6001debfc3dSmrgWhen the garbage collector is used, the objects are allocated using the 6011debfc3dSmrgso-called typed memory allocation mechanism available in the 6021debfc3dSmrgBoehm-Demers-Weiser collector. This mode requires precise information on 6031debfc3dSmrgwhere pointers are located inside objects. This information is computed 6041debfc3dSmrgonce per class, immediately after the class has been initialized. 6051debfc3dSmrg 6061debfc3dSmrgThere is a new runtime function @code{class_ivar_set_gcinvisible()} 6071debfc3dSmrgwhich can be used to declare a so-called @dfn{weak pointer} 6081debfc3dSmrgreference. Such a pointer is basically hidden for the garbage collector; 6091debfc3dSmrgthis can be useful in certain situations, especially when you want to 6101debfc3dSmrgkeep track of the allocated objects, yet allow them to be 6111debfc3dSmrgcollected. This kind of pointers can only be members of objects, you 6121debfc3dSmrgcannot declare a global pointer as a weak reference. Every type which is 6131debfc3dSmrga pointer type can be declared a weak pointer, including @code{id}, 6141debfc3dSmrg@code{Class} and @code{SEL}. 6151debfc3dSmrg 6161debfc3dSmrgHere is an example of how to use this feature. Suppose you want to 6171debfc3dSmrgimplement a class whose instances hold a weak pointer reference; the 6181debfc3dSmrgfollowing class does this: 6191debfc3dSmrg 6201debfc3dSmrg@smallexample 6211debfc3dSmrg 6221debfc3dSmrg@@interface WeakPointer : Object 6231debfc3dSmrg@{ 6241debfc3dSmrg const void* weakPointer; 6251debfc3dSmrg@} 6261debfc3dSmrg 6271debfc3dSmrg- initWithPointer:(const void*)p; 6281debfc3dSmrg- (const void*)weakPointer; 6291debfc3dSmrg@@end 6301debfc3dSmrg 6311debfc3dSmrg 6321debfc3dSmrg@@implementation WeakPointer 6331debfc3dSmrg 6341debfc3dSmrg+ (void)initialize 6351debfc3dSmrg@{ 6361debfc3dSmrg if (self == objc_lookUpClass ("WeakPointer")) 6371debfc3dSmrg class_ivar_set_gcinvisible (self, "weakPointer", YES); 6381debfc3dSmrg@} 6391debfc3dSmrg 6401debfc3dSmrg- initWithPointer:(const void*)p 6411debfc3dSmrg@{ 6421debfc3dSmrg weakPointer = p; 6431debfc3dSmrg return self; 6441debfc3dSmrg@} 6451debfc3dSmrg 6461debfc3dSmrg- (const void*)weakPointer 6471debfc3dSmrg@{ 6481debfc3dSmrg return weakPointer; 6491debfc3dSmrg@} 6501debfc3dSmrg 6511debfc3dSmrg@@end 6521debfc3dSmrg 6531debfc3dSmrg@end smallexample 6541debfc3dSmrg 6551debfc3dSmrgWeak pointers are supported through a new type character specifier 6561debfc3dSmrgrepresented by the @samp{!} character. The 6571debfc3dSmrg@code{class_ivar_set_gcinvisible()} function adds or removes this 6581debfc3dSmrgspecifier to the string type description of the instance variable named 6591debfc3dSmrgas argument. 6601debfc3dSmrg 6611debfc3dSmrg@c ========================================================================= 6621debfc3dSmrg@node Constant string objects 6631debfc3dSmrg@section Constant String Objects 6641debfc3dSmrg 6651debfc3dSmrgGNU Objective-C provides constant string objects that are generated 6661debfc3dSmrgdirectly by the compiler. You declare a constant string object by 6671debfc3dSmrgprefixing a C constant string with the character @samp{@@}: 6681debfc3dSmrg 6691debfc3dSmrg@smallexample 6701debfc3dSmrg id myString = @@"this is a constant string object"; 6711debfc3dSmrg@end smallexample 6721debfc3dSmrg 6731debfc3dSmrgThe constant string objects are by default instances of the 6741debfc3dSmrg@code{NXConstantString} class which is provided by the GNU Objective-C 6751debfc3dSmrgruntime. To get the definition of this class you must include the 6761debfc3dSmrg@file{objc/NXConstStr.h} header file. 6771debfc3dSmrg 6781debfc3dSmrgUser defined libraries may want to implement their own constant string 6791debfc3dSmrgclass. To be able to support them, the GNU Objective-C compiler provides 6801debfc3dSmrga new command line options @option{-fconstant-string-class=@var{class-name}}. 6811debfc3dSmrgThe provided class should adhere to a strict structure, the same 6821debfc3dSmrgas @code{NXConstantString}'s structure: 6831debfc3dSmrg 6841debfc3dSmrg@smallexample 6851debfc3dSmrg 6861debfc3dSmrg@@interface MyConstantStringClass 6871debfc3dSmrg@{ 6881debfc3dSmrg Class isa; 6891debfc3dSmrg char *c_string; 6901debfc3dSmrg unsigned int len; 6911debfc3dSmrg@} 6921debfc3dSmrg@@end 6931debfc3dSmrg 6941debfc3dSmrg@end smallexample 6951debfc3dSmrg 6961debfc3dSmrg@code{NXConstantString} inherits from @code{Object}; user class 6971debfc3dSmrglibraries may choose to inherit the customized constant string class 6981debfc3dSmrgfrom a different class than @code{Object}. There is no requirement in 6991debfc3dSmrgthe methods the constant string class has to implement, but the final 7001debfc3dSmrgivar layout of the class must be the compatible with the given 7011debfc3dSmrgstructure. 7021debfc3dSmrg 7031debfc3dSmrgWhen the compiler creates the statically allocated constant string 7041debfc3dSmrgobject, the @code{c_string} field will be filled by the compiler with 7051debfc3dSmrgthe string; the @code{length} field will be filled by the compiler with 7061debfc3dSmrgthe string length; the @code{isa} pointer will be filled with 7071debfc3dSmrg@code{NULL} by the compiler, and it will later be fixed up automatically 7081debfc3dSmrgat runtime by the GNU Objective-C runtime library to point to the class 7091debfc3dSmrgwhich was set by the @option{-fconstant-string-class} option when the 7101debfc3dSmrgobject file is loaded (if you wonder how it works behind the scenes, the 7111debfc3dSmrgname of the class to use, and the list of static objects to fixup, are 7121debfc3dSmrgstored by the compiler in the object file in a place where the GNU 7131debfc3dSmrgruntime library will find them at runtime). 7141debfc3dSmrg 7151debfc3dSmrgAs a result, when a file is compiled with the 7161debfc3dSmrg@option{-fconstant-string-class} option, all the constant string objects 7171debfc3dSmrgwill be instances of the class specified as argument to this option. It 7181debfc3dSmrgis possible to have multiple compilation units referring to different 7191debfc3dSmrgconstant string classes, neither the compiler nor the linker impose any 7201debfc3dSmrgrestrictions in doing this. 7211debfc3dSmrg 7221debfc3dSmrg@c ========================================================================= 7231debfc3dSmrg@node compatibility_alias 7241debfc3dSmrg@section @code{compatibility_alias} 7251debfc3dSmrg 7261debfc3dSmrgThe keyword @code{@@compatibility_alias} allows you to define a class name 7271debfc3dSmrgas equivalent to another class name. For example: 7281debfc3dSmrg 7291debfc3dSmrg@smallexample 7301debfc3dSmrg@@compatibility_alias WOApplication GSWApplication; 7311debfc3dSmrg@end smallexample 7321debfc3dSmrg 7331debfc3dSmrgtells the compiler that each time it encounters @code{WOApplication} as 7341debfc3dSmrga class name, it should replace it with @code{GSWApplication} (that is, 7351debfc3dSmrg@code{WOApplication} is just an alias for @code{GSWApplication}). 7361debfc3dSmrg 7371debfc3dSmrgThere are some constraints on how this can be used--- 7381debfc3dSmrg 7391debfc3dSmrg@itemize @bullet 7401debfc3dSmrg 7411debfc3dSmrg@item @code{WOApplication} (the alias) must not be an existing class; 7421debfc3dSmrg 7431debfc3dSmrg@item @code{GSWApplication} (the real class) must be an existing class. 7441debfc3dSmrg 7451debfc3dSmrg@end itemize 7461debfc3dSmrg 7471debfc3dSmrg@c ========================================================================= 7481debfc3dSmrg@node Exceptions 7491debfc3dSmrg@section Exceptions 7501debfc3dSmrg 7511debfc3dSmrgGNU Objective-C provides exception support built into the language, as 7521debfc3dSmrgin the following example: 7531debfc3dSmrg 7541debfc3dSmrg@smallexample 7551debfc3dSmrg @@try @{ 7561debfc3dSmrg @dots{} 7571debfc3dSmrg @@throw expr; 7581debfc3dSmrg @dots{} 7591debfc3dSmrg @} 7601debfc3dSmrg @@catch (AnObjCClass *exc) @{ 7611debfc3dSmrg @dots{} 7621debfc3dSmrg @@throw expr; 7631debfc3dSmrg @dots{} 7641debfc3dSmrg @@throw; 7651debfc3dSmrg @dots{} 7661debfc3dSmrg @} 7671debfc3dSmrg @@catch (AnotherClass *exc) @{ 7681debfc3dSmrg @dots{} 7691debfc3dSmrg @} 7701debfc3dSmrg @@catch (id allOthers) @{ 7711debfc3dSmrg @dots{} 7721debfc3dSmrg @} 7731debfc3dSmrg @@finally @{ 7741debfc3dSmrg @dots{} 7751debfc3dSmrg @@throw expr; 7761debfc3dSmrg @dots{} 7771debfc3dSmrg @} 7781debfc3dSmrg@end smallexample 7791debfc3dSmrg 7801debfc3dSmrgThe @code{@@throw} statement may appear anywhere in an Objective-C or 7811debfc3dSmrgObjective-C++ program; when used inside of a @code{@@catch} block, the 7821debfc3dSmrg@code{@@throw} may appear without an argument (as shown above), in 7831debfc3dSmrgwhich case the object caught by the @code{@@catch} will be rethrown. 7841debfc3dSmrg 7851debfc3dSmrgNote that only (pointers to) Objective-C objects may be thrown and 7861debfc3dSmrgcaught using this scheme. When an object is thrown, it will be caught 7871debfc3dSmrgby the nearest @code{@@catch} clause capable of handling objects of 7881debfc3dSmrgthat type, analogously to how @code{catch} blocks work in C++ and 7891debfc3dSmrgJava. A @code{@@catch(id @dots{})} clause (as shown above) may also 7901debfc3dSmrgbe provided to catch any and all Objective-C exceptions not caught by 7911debfc3dSmrgprevious @code{@@catch} clauses (if any). 7921debfc3dSmrg 7931debfc3dSmrgThe @code{@@finally} clause, if present, will be executed upon exit 7941debfc3dSmrgfrom the immediately preceding @code{@@try @dots{} @@catch} section. 7951debfc3dSmrgThis will happen regardless of whether any exceptions are thrown, 7961debfc3dSmrgcaught or rethrown inside the @code{@@try @dots{} @@catch} section, 7971debfc3dSmrganalogously to the behavior of the @code{finally} clause in Java. 7981debfc3dSmrg 7991debfc3dSmrgThere are several caveats to using the new exception mechanism: 8001debfc3dSmrg 8011debfc3dSmrg@itemize @bullet 8021debfc3dSmrg@item 8031debfc3dSmrgThe @option{-fobjc-exceptions} command line option must be used when 8041debfc3dSmrgcompiling Objective-C files that use exceptions. 8051debfc3dSmrg 8061debfc3dSmrg@item 8071debfc3dSmrgWith the GNU runtime, exceptions are always implemented as ``native'' 8081debfc3dSmrgexceptions and it is recommended that the @option{-fexceptions} and 8091debfc3dSmrg@option{-shared-libgcc} options are used when linking. 8101debfc3dSmrg 8111debfc3dSmrg@item 8121debfc3dSmrgWith the NeXT runtime, although currently designed to be binary 8131debfc3dSmrgcompatible with @code{NS_HANDLER}-style idioms provided by the 8141debfc3dSmrg@code{NSException} class, the new exceptions can only be used on Mac 8151debfc3dSmrgOS X 10.3 (Panther) and later systems, due to additional functionality 8161debfc3dSmrgneeded in the NeXT Objective-C runtime. 8171debfc3dSmrg 8181debfc3dSmrg@item 8191debfc3dSmrgAs mentioned above, the new exceptions do not support handling 8201debfc3dSmrgtypes other than Objective-C objects. Furthermore, when used from 8211debfc3dSmrgObjective-C++, the Objective-C exception model does not interoperate with C++ 8221debfc3dSmrgexceptions at this time. This means you cannot @code{@@throw} an exception 8231debfc3dSmrgfrom Objective-C and @code{catch} it in C++, or vice versa 8241debfc3dSmrg(i.e., @code{throw @dots{} @@catch}). 8251debfc3dSmrg@end itemize 8261debfc3dSmrg 8271debfc3dSmrg@c ========================================================================= 8281debfc3dSmrg@node Synchronization 8291debfc3dSmrg@section Synchronization 8301debfc3dSmrg 8311debfc3dSmrgGNU Objective-C provides support for synchronized blocks: 8321debfc3dSmrg 8331debfc3dSmrg@smallexample 8341debfc3dSmrg @@synchronized (ObjCClass *guard) @{ 8351debfc3dSmrg @dots{} 8361debfc3dSmrg @} 8371debfc3dSmrg@end smallexample 8381debfc3dSmrg 8391debfc3dSmrgUpon entering the @code{@@synchronized} block, a thread of execution 8401debfc3dSmrgshall first check whether a lock has been placed on the corresponding 8411debfc3dSmrg@code{guard} object by another thread. If it has, the current thread 8421debfc3dSmrgshall wait until the other thread relinquishes its lock. Once 8431debfc3dSmrg@code{guard} becomes available, the current thread will place its own 8441debfc3dSmrglock on it, execute the code contained in the @code{@@synchronized} 8451debfc3dSmrgblock, and finally relinquish the lock (thereby making @code{guard} 8461debfc3dSmrgavailable to other threads). 8471debfc3dSmrg 8481debfc3dSmrgUnlike Java, Objective-C does not allow for entire methods to be 8491debfc3dSmrgmarked @code{@@synchronized}. Note that throwing exceptions out of 8501debfc3dSmrg@code{@@synchronized} blocks is allowed, and will cause the guarding 8511debfc3dSmrgobject to be unlocked properly. 8521debfc3dSmrg 8531debfc3dSmrgBecause of the interactions between synchronization and exception 8541debfc3dSmrghandling, you can only use @code{@@synchronized} when compiling with 8551debfc3dSmrgexceptions enabled, that is with the command line option 8561debfc3dSmrg@option{-fobjc-exceptions}. 8571debfc3dSmrg 8581debfc3dSmrg 8591debfc3dSmrg@c ========================================================================= 8601debfc3dSmrg@node Fast enumeration 8611debfc3dSmrg@section Fast Enumeration 8621debfc3dSmrg 8631debfc3dSmrg@menu 8641debfc3dSmrg* Using fast enumeration:: 8651debfc3dSmrg* c99-like fast enumeration syntax:: 8661debfc3dSmrg* Fast enumeration details:: 8671debfc3dSmrg* Fast enumeration protocol:: 8681debfc3dSmrg@end menu 8691debfc3dSmrg 8701debfc3dSmrg@c ================================ 8711debfc3dSmrg@node Using fast enumeration 8721debfc3dSmrg@subsection Using Fast Enumeration 8731debfc3dSmrg 8741debfc3dSmrgGNU Objective-C provides support for the fast enumeration syntax: 8751debfc3dSmrg 8761debfc3dSmrg@smallexample 8771debfc3dSmrg id array = @dots{}; 8781debfc3dSmrg id object; 8791debfc3dSmrg 8801debfc3dSmrg for (object in array) 8811debfc3dSmrg @{ 8821debfc3dSmrg /* Do something with 'object' */ 8831debfc3dSmrg @} 8841debfc3dSmrg@end smallexample 8851debfc3dSmrg 8861debfc3dSmrg@code{array} needs to be an Objective-C object (usually a collection 8871debfc3dSmrgobject, for example an array, a dictionary or a set) which implements 8881debfc3dSmrgthe ``Fast Enumeration Protocol'' (see below). If you are using a 8891debfc3dSmrgFoundation library such as GNUstep Base or Apple Cocoa Foundation, all 8901debfc3dSmrgcollection objects in the library implement this protocol and can be 8911debfc3dSmrgused in this way. 8921debfc3dSmrg 8931debfc3dSmrgThe code above would iterate over all objects in @code{array}. For 8941debfc3dSmrgeach of them, it assigns it to @code{object}, then executes the 8951debfc3dSmrg@code{Do something with 'object'} statements. 8961debfc3dSmrg 8971debfc3dSmrgHere is a fully worked-out example using a Foundation library (which 8981debfc3dSmrgprovides the implementation of @code{NSArray}, @code{NSString} and 8991debfc3dSmrg@code{NSLog}): 9001debfc3dSmrg 9011debfc3dSmrg@smallexample 9021debfc3dSmrg NSArray *array = [NSArray arrayWithObjects: @@"1", @@"2", @@"3", nil]; 9031debfc3dSmrg NSString *object; 9041debfc3dSmrg 9051debfc3dSmrg for (object in array) 9061debfc3dSmrg NSLog (@@"Iterating over %@@", object); 9071debfc3dSmrg@end smallexample 9081debfc3dSmrg 9091debfc3dSmrg 9101debfc3dSmrg@c ================================ 9111debfc3dSmrg@node c99-like fast enumeration syntax 9121debfc3dSmrg@subsection C99-Like Fast Enumeration Syntax 9131debfc3dSmrg 9141debfc3dSmrgA c99-like declaration syntax is also allowed: 9151debfc3dSmrg 9161debfc3dSmrg@smallexample 9171debfc3dSmrg id array = @dots{}; 9181debfc3dSmrg 9191debfc3dSmrg for (id object in array) 9201debfc3dSmrg @{ 9211debfc3dSmrg /* Do something with 'object' */ 9221debfc3dSmrg @} 9231debfc3dSmrg@end smallexample 9241debfc3dSmrg 9251debfc3dSmrgthis is completely equivalent to: 9261debfc3dSmrg 9271debfc3dSmrg@smallexample 9281debfc3dSmrg id array = @dots{}; 9291debfc3dSmrg 9301debfc3dSmrg @{ 9311debfc3dSmrg id object; 9321debfc3dSmrg for (object in array) 9331debfc3dSmrg @{ 9341debfc3dSmrg /* Do something with 'object' */ 9351debfc3dSmrg @} 9361debfc3dSmrg @} 9371debfc3dSmrg@end smallexample 9381debfc3dSmrg 9391debfc3dSmrgbut can save some typing. 9401debfc3dSmrg 9411debfc3dSmrgNote that the option @option{-std=c99} is not required to allow this 9421debfc3dSmrgsyntax in Objective-C. 9431debfc3dSmrg 9441debfc3dSmrg@c ================================ 9451debfc3dSmrg@node Fast enumeration details 9461debfc3dSmrg@subsection Fast Enumeration Details 9471debfc3dSmrg 9481debfc3dSmrgHere is a more technical description with the gory details. Consider the code 9491debfc3dSmrg 9501debfc3dSmrg@smallexample 9511debfc3dSmrg for (@var{object expression} in @var{collection expression}) 9521debfc3dSmrg @{ 9531debfc3dSmrg @var{statements} 9541debfc3dSmrg @} 9551debfc3dSmrg@end smallexample 9561debfc3dSmrg 9571debfc3dSmrghere is what happens when you run it: 9581debfc3dSmrg 9591debfc3dSmrg@itemize @bullet 9601debfc3dSmrg@item 9611debfc3dSmrg@code{@var{collection expression}} is evaluated exactly once and the 9621debfc3dSmrgresult is used as the collection object to iterate over. This means 9631debfc3dSmrgit is safe to write code such as @code{for (object in [NSDictionary 9641debfc3dSmrgkeyEnumerator]) @dots{}}. 9651debfc3dSmrg 9661debfc3dSmrg@item 9671debfc3dSmrgthe iteration is implemented by the compiler by repeatedly getting 9681debfc3dSmrgbatches of objects from the collection object using the fast 9691debfc3dSmrgenumeration protocol (see below), then iterating over all objects in 9701debfc3dSmrgthe batch. This is faster than a normal enumeration where objects are 9711debfc3dSmrgretrieved one by one (hence the name ``fast enumeration''). 9721debfc3dSmrg 9731debfc3dSmrg@item 9741debfc3dSmrgif there are no objects in the collection, then 9751debfc3dSmrg@code{@var{object expression}} is set to @code{nil} and the loop 9761debfc3dSmrgimmediately terminates. 9771debfc3dSmrg 9781debfc3dSmrg@item 9791debfc3dSmrgif there are objects in the collection, then for each object in the 9801debfc3dSmrgcollection (in the order they are returned) @code{@var{object expression}} 9811debfc3dSmrgis set to the object, then @code{@var{statements}} are executed. 9821debfc3dSmrg 9831debfc3dSmrg@item 9841debfc3dSmrg@code{@var{statements}} can contain @code{break} and @code{continue} 9851debfc3dSmrgcommands, which will abort the iteration or skip to the next loop 9861debfc3dSmrgiteration as expected. 9871debfc3dSmrg 9881debfc3dSmrg@item 9891debfc3dSmrgwhen the iteration ends because there are no more objects to iterate 9901debfc3dSmrgover, @code{@var{object expression}} is set to @code{nil}. This allows 9911debfc3dSmrgyou to determine whether the iteration finished because a @code{break} 9921debfc3dSmrgcommand was used (in which case @code{@var{object expression}} will remain 9931debfc3dSmrgset to the last object that was iterated over) or because it iterated 9941debfc3dSmrgover all the objects (in which case @code{@var{object expression}} will be 9951debfc3dSmrgset to @code{nil}). 9961debfc3dSmrg 9971debfc3dSmrg@item 9981debfc3dSmrg@code{@var{statements}} must not make any changes to the collection 9991debfc3dSmrgobject; if they do, it is a hard error and the fast enumeration 10001debfc3dSmrgterminates by invoking @code{objc_enumerationMutation}, a runtime 10011debfc3dSmrgfunction that normally aborts the program but which can be customized 10021debfc3dSmrgby Foundation libraries via @code{objc_set_mutation_handler} to do 10031debfc3dSmrgsomething different, such as raising an exception. 10041debfc3dSmrg 10051debfc3dSmrg@end itemize 10061debfc3dSmrg 10071debfc3dSmrg@c ================================ 10081debfc3dSmrg@node Fast enumeration protocol 10091debfc3dSmrg@subsection Fast Enumeration Protocol 10101debfc3dSmrg 10111debfc3dSmrgIf you want your own collection object to be usable with fast 10121debfc3dSmrgenumeration, you need to have it implement the method 10131debfc3dSmrg 10141debfc3dSmrg@smallexample 10151debfc3dSmrg- (unsigned long) countByEnumeratingWithState: (NSFastEnumerationState *)state 10161debfc3dSmrg objects: (id *)objects 10171debfc3dSmrg count: (unsigned long)len; 10181debfc3dSmrg@end smallexample 10191debfc3dSmrg 10201debfc3dSmrgwhere @code{NSFastEnumerationState} must be defined in your code as follows: 10211debfc3dSmrg 10221debfc3dSmrg@smallexample 10231debfc3dSmrgtypedef struct 10241debfc3dSmrg@{ 10251debfc3dSmrg unsigned long state; 10261debfc3dSmrg id *itemsPtr; 10271debfc3dSmrg unsigned long *mutationsPtr; 10281debfc3dSmrg unsigned long extra[5]; 10291debfc3dSmrg@} NSFastEnumerationState; 10301debfc3dSmrg@end smallexample 10311debfc3dSmrg 10321debfc3dSmrgIf no @code{NSFastEnumerationState} is defined in your code, the 10331debfc3dSmrgcompiler will automatically replace @code{NSFastEnumerationState *} 10341debfc3dSmrgwith @code{struct __objcFastEnumerationState *}, where that type is 10351debfc3dSmrgsilently defined by the compiler in an identical way. This can be 10361debfc3dSmrgconfusing and we recommend that you define 10371debfc3dSmrg@code{NSFastEnumerationState} (as shown above) instead. 10381debfc3dSmrg 10391debfc3dSmrgThe method is called repeatedly during a fast enumeration to retrieve 10401debfc3dSmrgbatches of objects. Each invocation of the method should retrieve the 10411debfc3dSmrgnext batch of objects. 10421debfc3dSmrg 10431debfc3dSmrgThe return value of the method is the number of objects in the current 10441debfc3dSmrgbatch; this should not exceed @code{len}, which is the maximum size of 10451debfc3dSmrga batch as requested by the caller. The batch itself is returned in 10461debfc3dSmrgthe @code{itemsPtr} field of the @code{NSFastEnumerationState} struct. 10471debfc3dSmrg 10481debfc3dSmrgTo help with returning the objects, the @code{objects} array is a C 10491debfc3dSmrgarray preallocated by the caller (on the stack) of size @code{len}. 10501debfc3dSmrgIn many cases you can put the objects you want to return in that 10511debfc3dSmrg@code{objects} array, then do @code{itemsPtr = objects}. But you 10521debfc3dSmrgdon't have to; if your collection already has the objects to return in 10531debfc3dSmrgsome form of C array, it could return them from there instead. 10541debfc3dSmrg 10551debfc3dSmrgThe @code{state} and @code{extra} fields of the 10561debfc3dSmrg@code{NSFastEnumerationState} structure allows your collection object 10571debfc3dSmrgto keep track of the state of the enumeration. In a simple array 10581debfc3dSmrgimplementation, @code{state} may keep track of the index of the last 10591debfc3dSmrgobject that was returned, and @code{extra} may be unused. 10601debfc3dSmrg 10611debfc3dSmrgThe @code{mutationsPtr} field of the @code{NSFastEnumerationState} is 10621debfc3dSmrgused to keep track of mutations. It should point to a number; before 10631debfc3dSmrgworking on each object, the fast enumeration loop will check that this 10641debfc3dSmrgnumber has not changed. If it has, a mutation has happened and the 10651debfc3dSmrgfast enumeration will abort. So, @code{mutationsPtr} could be set to 10661debfc3dSmrgpoint to some sort of version number of your collection, which is 10671debfc3dSmrgincreased by one every time there is a change (for example when an 10681debfc3dSmrgobject is added or removed). Or, if you are content with less strict 10691debfc3dSmrgmutation checks, it could point to the number of objects in your 10701debfc3dSmrgcollection or some other value that can be checked to perform an 10711debfc3dSmrgapproximate check that the collection has not been mutated. 10721debfc3dSmrg 10731debfc3dSmrgFinally, note how we declared the @code{len} argument and the return 10741debfc3dSmrgvalue to be of type @code{unsigned long}. They could also be declared 10751debfc3dSmrgto be of type @code{unsigned int} and everything would still work. 10761debfc3dSmrg 10771debfc3dSmrg@c ========================================================================= 10781debfc3dSmrg@node Messaging with the GNU Objective-C runtime 10791debfc3dSmrg@section Messaging with the GNU Objective-C Runtime 10801debfc3dSmrg 10811debfc3dSmrgThis section is specific for the GNU Objective-C runtime. If you are 10821debfc3dSmrgusing a different runtime, you can skip it. 10831debfc3dSmrg 10841debfc3dSmrgThe implementation of messaging in the GNU Objective-C runtime is 10851debfc3dSmrgdesigned to be portable, and so is based on standard C. 10861debfc3dSmrg 10871debfc3dSmrgSending a message in the GNU Objective-C runtime is composed of two 10881debfc3dSmrgseparate steps. First, there is a call to the lookup function, 10891debfc3dSmrg@code{objc_msg_lookup ()} (or, in the case of messages to super, 10901debfc3dSmrg@code{objc_msg_lookup_super ()}). This runtime function takes as 10911debfc3dSmrgargument the receiver and the selector of the method to be called; it 10921debfc3dSmrgreturns the @code{IMP}, that is a pointer to the function implementing 10931debfc3dSmrgthe method. The second step of method invocation consists of casting 10941debfc3dSmrgthis pointer function to the appropriate function pointer type, and 10951debfc3dSmrgcalling the function pointed to it with the right arguments. 10961debfc3dSmrg 10971debfc3dSmrgFor example, when the compiler encounters a method invocation such as 10981debfc3dSmrg@code{[object init]}, it compiles it into a call to 10991debfc3dSmrg@code{objc_msg_lookup (object, @@selector(init))} followed by a cast 11001debfc3dSmrgof the returned value to the appropriate function pointer type, and 11011debfc3dSmrgthen it calls it. 11021debfc3dSmrg 11031debfc3dSmrg@menu 11041debfc3dSmrg* Dynamically registering methods:: 11051debfc3dSmrg* Forwarding hook:: 11061debfc3dSmrg@end menu 11071debfc3dSmrg 11081debfc3dSmrg@c ========================================================================= 11091debfc3dSmrg@node Dynamically registering methods 11101debfc3dSmrg@subsection Dynamically Registering Methods 11111debfc3dSmrg 11121debfc3dSmrgIf @code{objc_msg_lookup()} does not find a suitable method 11131debfc3dSmrgimplementation, because the receiver does not implement the required 11141debfc3dSmrgmethod, it tries to see if the class can dynamically register the 11151debfc3dSmrgmethod. 11161debfc3dSmrg 11171debfc3dSmrgTo do so, the runtime checks if the class of the receiver implements 11181debfc3dSmrgthe method 11191debfc3dSmrg 11201debfc3dSmrg@smallexample 11211debfc3dSmrg+ (BOOL) resolveInstanceMethod: (SEL)selector; 11221debfc3dSmrg@end smallexample 11231debfc3dSmrg 11241debfc3dSmrgin the case of an instance method, or 11251debfc3dSmrg 11261debfc3dSmrg@smallexample 11271debfc3dSmrg+ (BOOL) resolveClassMethod: (SEL)selector; 11281debfc3dSmrg@end smallexample 11291debfc3dSmrg 11301debfc3dSmrgin the case of a class method. If the class implements it, the 11311debfc3dSmrgruntime invokes it, passing as argument the selector of the original 11321debfc3dSmrgmethod, and if it returns @code{YES}, the runtime tries the lookup 11331debfc3dSmrgagain, which could now succeed if a matching method was added 11341debfc3dSmrgdynamically by @code{+resolveInstanceMethod:} or 11351debfc3dSmrg@code{+resolveClassMethod:}. 11361debfc3dSmrg 11371debfc3dSmrgThis allows classes to dynamically register methods (by adding them to 11381debfc3dSmrgthe class using @code{class_addMethod}) when they are first called. 11391debfc3dSmrgTo do so, a class should implement @code{+resolveInstanceMethod:} (or, 11401debfc3dSmrgdepending on the case, @code{+resolveClassMethod:}) and have it 11411debfc3dSmrgrecognize the selectors of methods that can be registered dynamically 11421debfc3dSmrgat runtime, register them, and return @code{YES}. It should return 11431debfc3dSmrg@code{NO} for methods that it does not dynamically registered at 11441debfc3dSmrgruntime. 11451debfc3dSmrg 11461debfc3dSmrgIf @code{+resolveInstanceMethod:} (or @code{+resolveClassMethod:}) is 11471debfc3dSmrgnot implemented or returns @code{NO}, the runtime then tries the 11481debfc3dSmrgforwarding hook. 11491debfc3dSmrg 11501debfc3dSmrgSupport for @code{+resolveInstanceMethod:} and 11511debfc3dSmrg@code{resolveClassMethod:} was added to the GNU Objective-C runtime in 11521debfc3dSmrgGCC version 4.6. 11531debfc3dSmrg 11541debfc3dSmrg@c ========================================================================= 11551debfc3dSmrg@node Forwarding hook 11561debfc3dSmrg@subsection Forwarding Hook 11571debfc3dSmrg 11581debfc3dSmrgThe GNU Objective-C runtime provides a hook, called 11591debfc3dSmrg@code{__objc_msg_forward2}, which is called by 11601debfc3dSmrg@code{objc_msg_lookup()} when it cannot find a method implementation in 11611debfc3dSmrgthe runtime tables and after calling @code{+resolveInstanceMethod:} 11621debfc3dSmrgand @code{+resolveClassMethod:} has been attempted and did not succeed 11631debfc3dSmrgin dynamically registering the method. 11641debfc3dSmrg 11651debfc3dSmrgTo configure the hook, you set the global variable 11661debfc3dSmrg@code{__objc_msg_forward2} to a function with the same argument and 11671debfc3dSmrgreturn types of @code{objc_msg_lookup()}. When 11681debfc3dSmrg@code{objc_msg_lookup()} cannot find a method implementation, it 11691debfc3dSmrginvokes the hook function you provided to get a method implementation 11701debfc3dSmrgto return. So, in practice @code{__objc_msg_forward2} allows you to 11711debfc3dSmrgextend @code{objc_msg_lookup()} by adding some custom code that is 11721debfc3dSmrgcalled to do a further lookup when no standard method implementation 11731debfc3dSmrgcan be found using the normal lookup. 11741debfc3dSmrg 11751debfc3dSmrgThis hook is generally reserved for ``Foundation'' libraries such as 11761debfc3dSmrgGNUstep Base, which use it to implement their high-level method 11771debfc3dSmrgforwarding API, typically based around the @code{forwardInvocation:} 11781debfc3dSmrgmethod. So, unless you are implementing your own ``Foundation'' 11791debfc3dSmrglibrary, you should not set this hook. 11801debfc3dSmrg 11811debfc3dSmrgIn a typical forwarding implementation, the @code{__objc_msg_forward2} 11821debfc3dSmrghook function determines the argument and return type of the method 11831debfc3dSmrgthat is being looked up, and then creates a function that takes these 11841debfc3dSmrgarguments and has that return type, and returns it to the caller. 11851debfc3dSmrgCreating this function is non-trivial and is typically performed using 11861debfc3dSmrga dedicated library such as @code{libffi}. 11871debfc3dSmrg 11881debfc3dSmrgThe forwarding method implementation thus created is returned by 11891debfc3dSmrg@code{objc_msg_lookup()} and is executed as if it was a normal method 11901debfc3dSmrgimplementation. When the forwarding method implementation is called, 11911debfc3dSmrgit is usually expected to pack all arguments into some sort of object 11921debfc3dSmrg(typically, an @code{NSInvocation} in a ``Foundation'' library), and 11931debfc3dSmrghand it over to the programmer (@code{forwardInvocation:}) who is then 11941debfc3dSmrgallowed to manipulate the method invocation using a high-level API 11951debfc3dSmrgprovided by the ``Foundation'' library. For example, the programmer 11961debfc3dSmrgmay want to examine the method invocation arguments and name and 11971debfc3dSmrgpotentially change them before forwarding the method invocation to one 11981debfc3dSmrgor more local objects (@code{performInvocation:}) or even to remote 11991debfc3dSmrgobjects (by using Distributed Objects or some other mechanism). When 12001debfc3dSmrgall this completes, the return value is passed back and must be 12011debfc3dSmrgreturned correctly to the original caller. 12021debfc3dSmrg 12031debfc3dSmrgNote that the GNU Objective-C runtime currently provides no support 12041debfc3dSmrgfor method forwarding or method invocations other than the 12051debfc3dSmrg@code{__objc_msg_forward2} hook. 12061debfc3dSmrg 12071debfc3dSmrgIf the forwarding hook does not exist or returns @code{NULL}, the 12081debfc3dSmrgruntime currently attempts forwarding using an older, deprecated API, 12091debfc3dSmrgand if that fails, it aborts the program. In future versions of the 12101debfc3dSmrgGNU Objective-C runtime, the runtime will immediately abort. 1211