objc-features.texi
上传用户:shenzhenrh
上传日期:2013-05-12
资源大小:2904k
文件大小:12k
源码类别:

信息检索与抽取

开发平台:

Unix_Linux

  1. input texinfo  @c -*-texinfo-*-
  2. @c %**start of header 
  3. @setfilename objc-features.info
  4. @settitle GNU Objective-C runtime features
  5. @setchapternewpage odd
  6. @c %**end of header
  7.      
  8. @node Top, Executing code before main, , (dir), (dir)
  9. @comment  node-name,  next,  previous,  up
  10. @chapter GNU Objective-C runtime features
  11. This document is meant to describe some of the GNU Objective-C runtime
  12. features. It is not intended to teach you Objective-C, there are several
  13. resources on the Internet that present the language.  Questions and
  14. comments about this document to Ovidiu Predescu
  15. @code{<ovidiu@@cup.hp.com>}.
  16. @menu
  17. * Executing code before main::
  18. * Type encoding::
  19. * Garbage Collection::
  20. @end menu
  21. @node Executing code before main, What you can and what you cannot do in +load, Top, Top
  22. @section @code{+load}: Executing code before main
  23. The GNU Objective-C runtime provides a way that allows you to execute
  24. code before the execution of the program enters the @code{main}
  25. function. The code is executed on a per-class and a per-category basis,
  26. through a special class method @code{+load}.
  27. This facility is very useful if you want to initialize global variables
  28. which can be accessed by the program directly, without sending a message
  29. to the class first. The usual way to initialize global variables, in the
  30. @code{+initialize} method, might not be useful because
  31. @code{+initialize} is only called when the first message is sent to a
  32. class object, which in some cases could be too late.
  33. Suppose for example you have a @code{FileStream} class that declares
  34. @code{Stdin}, @code{Stdout} and @code{Stderr} as global variables, like
  35. below:
  36. @example
  37.             
  38. FileStream *Stdin = nil;                                              
  39. FileStream *Stdout = nil;                                          
  40. FileStream *Stderr = nil;                                                
  41.             
  42. @@implementation FileStream                                               
  43.           
  44. + (void)initialize                                                 
  45. @{
  46.     Stdin = [[FileStream new] initWithFd:0];                           
  47.     Stdout = [[FileStream new] initWithFd:1];                           
  48.     Stderr = [[FileStream new] initWithFd:2];
  49. @}
  50.  
  51. /* Other methods here */
  52. @@end
  53. @end example
  54. In this example, the initialization of @code{Stdin}, @code{Stdout} and
  55. @code{Stderr} in @code{+initialize} occurs too late. The programmer can
  56. send a message to one of these objects before the variables are actually
  57. initialized, thus sending messages to the @code{nil} object. The
  58. @code{+initialize} method which actually initializes the global
  59. variables is not invoked until the first message is sent to the class
  60. object. The solution would require these variables to be initialized
  61. just before entering @code{main}.
  62. The correct solution of the above problem is to use the @code{+load}
  63. method instead of @code{+initialize}:
  64. @example
  65. @@implementation FileStream                                             
  66.  
  67. + (void)load                                 
  68. @{
  69.     Stdin = [[FileStream new] initWithFd:0];
  70.     Stdout = [[FileStream new] initWithFd:1];
  71.     Stderr = [[FileStream new] initWithFd:2];
  72. @}
  73.  
  74. /* Other methods here */                                               
  75. @@end
  76. @end example
  77.  
  78. The @code{+load} is a method that is not overridden by categories. If a
  79. class and a category of it both implement @code{+load}, both methods are
  80. invoked.  This allows some additional initializations to be performed in
  81. a category.
  82.    
  83. This mechanism is not intended to be a replacement for @code{+initialize}.
  84. You should be aware of its limitations when you decide to use it
  85. instead of @code{+initialize}.
  86. @menu
  87. * What you can and what you cannot do in +load::
  88. @end menu
  89. @node What you can and what you cannot do in +load, Type encoding, Executing code before main, Executing code before main
  90. @subsection What you can and what you cannot do in @code{+load}
  91. The +load implementation in the GNU runtime guarantees you the following
  92. things:
  93. @itemize @bullet
  94. @item
  95. you can write whatever C code you like;
  96. @item
  97. you can send messages to Objective-C constant strings (@@"this is a
  98. constant string");
  99. @item
  100. you can allocate and send messages to objects whose class is implemented
  101. in the same file;
  102. @item
  103. the @code{+load} implementation of all super classes of a class are executed before the @code{+load} of that class is executed;
  104. @item
  105. the @code{+load} implementation of a class is executed before the
  106. @code{+load} implementation of any category.
  107. @end itemize
  108. In particular, the following things, even if they can work in a
  109. particular case, are not guaranteed:
  110. @itemize @bullet
  111. @item
  112. allocation of or sending messages to arbitrary objects;
  113. @item
  114. allocation of or sending messages to objects whose classes have a
  115. category implemented in the same file;
  116. @end itemize
  117. You should make no assumptions about receiving @code{+load} in sibling
  118. classes when you write @code{+load} of a class. The order in which
  119. sibling classes receive @code{+load} is not guaranteed.
  120.     
  121. The order in which @code{+load} and @code{+initialize} are called could
  122. be problematic if this matters. If you don't allocate objects inside
  123. @code{+load}, it is guaranteed that @code{+load} is called before
  124. @code{+initialize}. If you create an object inside @code{+load} the
  125. @code{+initialize} method of object's class is invoked even if
  126. @code{+load} was not invoked. Note if you explicitly call @code{+load}
  127. on a class, @code{+initialize} will be called first. To avoid possible
  128. problems try to implement only one of these methods.
  129. The @code{+load} method is also invoked when a bundle is dynamically
  130. loaded into your running program. This happens automatically without any
  131. intervening operation from you. When you write bundles and you need to
  132. write @code{+load} you can safely create and send messages to objects whose
  133. classes already exist in the running program. The same restrictions as
  134. above apply to classes defined in bundle.
  135. @node Type encoding, Garbage Collection, What you can and what you cannot do in +load, Top
  136. @section Type encoding
  137. The Objective-C compiler generates type encodings for all the
  138. types. These type encodings are used at runtime to find out information
  139. about selectors and methods and about objects and classes.
  140. The types are encoded in the following way:
  141. @c @sp 1
  142. @multitable @columnfractions .25 .75
  143. @item @code{char}                      
  144. @tab @code{c}
  145. @item @code{unsigned char}             
  146. @tab @code{C}
  147. @item @code{short}                     
  148. @tab @code{s}
  149. @item @code{unsigned short}            
  150. @tab @code{S}
  151. @item @code{int}                       
  152. @tab @code{i}
  153. @item @code{unsigned int}              
  154. @tab @code{I}
  155. @item @code{long}                      
  156. @tab @code{l}
  157. @item @code{unsigned long}             
  158. @tab @code{L}
  159. @item @code{long long}                 
  160. @tab @code{q}
  161. @item @code{unsigned long long}        
  162. @tab @code{Q}
  163. @item @code{float}                     
  164. @tab @code{f}
  165. @item @code{double}                    
  166. @tab @code{d}
  167. @item @code{void}                      
  168. @tab @code{v}
  169. @item @code{id}                        
  170. @tab @code{@@}
  171. @item @code{Class}                     
  172. @tab @code{#}
  173. @item @code{SEL}                       
  174. @tab @code{:}
  175. @item @code{char*}                     
  176. @tab @code{*}
  177. @item unknown type                     
  178. @tab @code{?}
  179. @item bitfields                 
  180. @tab @code{b} followed by the starting position of the bitfield, the type of the bitfield and the size of the bitfield (the bitfields encoding was changed from the NeXT's compiler encoding, see below)
  181. @end multitable
  182. @c @sp 1
  183. The encoding of bitfields has changed to allow bitfields to be properly
  184. handled by the runtime functions that compute sizes and alignments of
  185. types that contain bitfields. The previous encoding contained only the
  186. size of the bitfield. Using only this information it is not possible to
  187. reliably compute the size occupied by the bitfield. This is very
  188. important in the presence of the Boehm's garbage collector because the
  189. objects are allocated using the typed memory facility available in this
  190. collector. The typed memory allocation requires information about where
  191. the pointers are located inside the object.
  192. The position in the bitfield is the position, counting in bits, of the
  193. bit closest to the beginning of the structure.
  194. The non-atomic types are encoded as follows:
  195. @c @sp 1
  196. @multitable @columnfractions .2 .8
  197. @item pointers          
  198. @tab @code{'^'} followed by the pointed type.
  199. @item arrays
  200. @tab @code{'['} followed by the number of elements in the array followed by the type of the elements followed by @code{']'}
  201. @item structures
  202. @tab @code{'@{'} followed by the name of the structure (or '?' if the structure is unnamed), the '=' sign, the type of the members and by @code{'@}'}
  203. @item unions
  204. @tab @code{'('} followed by the name of the structure (or '?' if the union is unnamed), the '=' sign, the type of the members followed by @code{')'}
  205. @end multitable
  206. Here are some types and their encodings, as they are generated by the
  207. compiler on a i386 machine:
  208. @sp 1
  209. @multitable @columnfractions .25 .75
  210. @item Objective-C type
  211. @tab Compiler encoding
  212. @item
  213. @example
  214. int a[10];
  215. @end example
  216. @tab @code{[10i]}
  217. @item
  218. @example
  219. struct @{
  220.   int i;
  221.   float f[3];
  222.   int a:3;
  223.   int b:2;
  224.   char c;
  225. @}
  226. @end example
  227. @tab @code{@{?=i[3f]b128i3b131i2c@}}
  228. @end multitable
  229. @sp 1
  230. In addition to the types the compiler also encodes the type
  231. specifiers. The table below describes the encoding of the current
  232. Objective-C type specifiers:
  233. @sp 1
  234. @multitable @columnfractions .25 .75
  235. @item Specifier
  236. @tab Encoding
  237. @item @code{const}              
  238. @tab @code{r}
  239. @item @code{in}                 
  240. @tab @code{n}
  241. @item @code{inout}              
  242. @tab @code{N}
  243. @item @code{out}                
  244. @tab @code{o}
  245. @item @code{bycopy}             
  246. @tab @code{O}
  247. @item @code{oneway}             
  248. @tab @code{V}
  249. @end multitable
  250. @sp 1
  251. The type specifiers are encoded just before the type. Unlike types
  252. however, the type specifiers are only encoded when they appear in method
  253. argument types.
  254. @node Garbage Collection, , Type encoding, Top
  255. @page
  256. @section Garbage Collection
  257. Support for a new memory management policy has been added by using a
  258. powerful conservative garbage collector, known as the
  259. Boehm-Demers-Weiser conservative garbage collector. It is available from
  260. @w{@uref{http://reality.sgi.com/employees/boehm_mti/gc.html}}.
  261. To enable the support for it you have to configure the compiler using an
  262. additional argument, @w{@kbd{--enable-objc-gc}}. You need to have
  263. garbage collector installed before building the compiler. This will
  264. build an additional runtime library which has several enhancements to
  265. support the garbage collector. The new library has a new name,
  266. @kbd{libobjc_gc.a} to not conflict with the non-garbage-collected
  267. library.
  268. When the garbage collector is used, the objects are allocated using the
  269. so-called typed memory allocation mechanism available in the
  270. Boehm-Demers-Weiser collector. This mode requires precise information on
  271. where pointers are located inside objects. This information is computed
  272. once per class, immediately after the class has been initialized.
  273. There is a new runtime function @code{class_ivar_set_gcinvisible()}
  274. which can be used to declare a so-called @strong{weak pointer}
  275. reference. Such a pointer is basically hidden for the garbage collector;
  276. this can be useful in certain situations, especially when you want to
  277. keep track of the allocated objects, yet allow them to be
  278. collected. This kind of pointers can only be members of objects, you
  279. cannot declare a global pointer as a weak reference. Every type which is
  280. a pointer type can be declared a weak pointer, including @code{id},
  281. @code{Class} and @code{SEL}.
  282. Here is an example of how to use this feature. Suppose you want to
  283. implement a class whose instances hold a weak pointer reference; the
  284. following class does this:
  285. @example
  286. @@interface WeakPointer : Object
  287. @{
  288.     const void* weakPointer;
  289. @}
  290. - initWithPointer:(const void*)p;
  291. - (const void*)weakPointer;
  292. @@end
  293. @@implementation WeakPointer
  294. + (void)initialize
  295. @{
  296.   class_ivar_set_gcinvisible (self, "weakPointer", YES);
  297. @}
  298. - initWithPointer:(const void*)p
  299. @{
  300.   weakPointer = p;
  301.   return self;
  302. @}
  303. - (const void*)weakPointer
  304. @{
  305.   return weakPointer;
  306. @}
  307. @@end
  308. @end example
  309. Weak pointers are supported through a new type character specifier
  310. represented by the @code{'!'} character. The
  311. @code{class_ivar_set_gcinvisible()} function adds or removes this
  312. specifier to the string type description of the instance variable named
  313. as argument.
  314. @bye