source: trunk/source/doc/src/objc-bridge.xml @ 8981

Last change on this file since 8981 was 8981, checked in by mikel, 11 years ago

additions to ObjC and ffi docs; many mechanical edits; some standardization of XML elements and formatting

File size: 43.8 KB
Line 
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"[
3          <!ENTITY rest "<varname>&amp;rest</varname>">
4          <!ENTITY key "<varname>&amp;key</varname>">
5          <!ENTITY optional "<varname>&amp;optional</varname>">
6          <!ENTITY body "<varname>&amp;body</varname>">
7          <!ENTITY aux "<varname>&amp;aux</varname>">
8          <!ENTITY allow-other-keys "<varname>&amp;allow-other-keys</varname>">
9          <!ENTITY CCL "Clozure CL">
10          ]>
11<chapter id="The-Objective-C-Bridge">
12  <title>The Objective-C Bridge</title>
13
14  <para>Mac OS X APIs use a language called Objective-C, which is
15    approximately C with some object-oriented extensions modeled on
16    Smalltalk.  The Objective-C bridge makes it possible to work with
17    Objective-C objects and classes from Lisp, and to define classes
18    in Lisp which can be used by Objective-C.</para>
19  <para>The ultimate purpose of the Objective-C and Cocoa bridges is
20    to make Cocoa (the standard user-interface framework on Mac OS X)
21    as easy as possible to use from &CCL;, in order to support the
22    development of GUI applications and IDEs on Mac OS X (and on any
23    platform that supports Objective-C, such as GNUStep).  The
24    eventual goal, which is much closer than it used to be, is
25    complete integration of Cocoa into CLOS.</para>
26  <para>The current release provides Lisp-like syntax and naming
27    conventions for the basic Objective-C operations, with automatic type
28    processing and messages checked for validity at compile-time.  It
29    also provides some convenience facilities for working with
30    Cocoa.</para>
31
32  <!-- ============================================================ -->
33  <sect1 id="Objective-C-Changes-1.2">
34    <title>Changes in 1.2</title>
35
36    <para>Version 1.2 of &CCL; exports most of the useful symbols
37    described in this chapter; in previous releases, most of them were
38    private in the <literal>CCL</literal> package.</para>
39
40    <para>There are several new reader macros that make it much more
41    convenient than before to refer to several classes of symbols used
42    with the Objective-C bridge. For a full description of these
43    reader-macros, see
44    the <link linkend="anchor_Foreign-Function-Interface-Dictionary">Foreign-Function-Interface
45    Dictionary</link>, especially the entries at the beginning,
46    describing reader macros.</para>
47
48    <para>As in previous releases, 32-bit versions of &CCL; use 32-bit
49    floats and integers in data structures that describe geometry,
50    font sizes and metrics, and so on. 64-bit versions of &CCL; use
51    64-bit values where appropriate.</para>
52
53    <para>The Objective-C bridge defines the
54      type <literal>NS:CGFLOAT</literal> as the Lisp type of the preferred
55      floating-point type on the current platform, and defines the
56      constant <literal>NS:+CGFLOAT+</literal>.  On DarwinPPC32, the foreign
57      types <literal>:cgfloat</literal>, <literal>:&lt;NSUI&gt;nteger</literal>,
58      and
59      <literal>:&lt;NSI&gt;nteger</literal> are defined by the Objective-C
60      bridge (as 32-bit float, 32-bit unsigned integer, and 32-bit
61      signed integer, respectively); these types are defined as 64-bit
62      variants in the 64-bit interfaces.</para>
63
64    <para>Every Objective-C class is now properly named, either with a
65      name exported from the <literal>NS</literal> package (in the case of a
66      predefined class declared in the interface files) or with the
67      name provided in the <literal>DEFCLASS</literal> form (with <literal>:METACLASS</literal>
68      <literal>NS:+NS-OBJECT</literal>) which defines the class from Lisp.
69      The class's Lisp name is now proclaimed to be a "static"
70      variable (as if by <literal>DEFSTATIC</literal>, as described in the
71      <link linkend="Static_Variables">"Static Variables"
72      section</link>) and given the class object as its value.  In
73      other words:</para>
74
75    <programlisting>
76(send (find-class 'ns:ns-application) 'shared-application)
77    </programlisting>
78
79  <para>and</para>
80
81    <programlisting>
82(send ns:ns-application 'shared-application)
83    </programlisting>
84
85  <para>are equivalent.  (Since it's not legal to bind a "static"
86  variable, it may be necessary to rename some things so that
87  unrelated variables whose names coincidentally conflict with
88  Objective-C class names don't do so.)</para>
89
90  </sect1>
91
92  <!-- ============================================================ -->
93  <sect1 id="Using-Objective-C-Classes">
94    <title>Using Objective-C Classes</title>
95
96    <para>The class of most standard CLOS classes is named
97      STANDARD-CLASS. In the Objective-C object model, each class is
98      an instance of a (usually unique) metaclass, which is itself an
99      instance of a "base" metaclass (often the metaclass of the class
100      named "NSObject".) So, the Objective-C class named "NSWindow"
101      and the Objective-C class "NSArray" are (sole) instances of
102      their distinct metaclasses whose names are also "NSWindow" and
103      "NSArray", respectively. (In the Objective-C world, it's much
104      more common and useful to specialize class behavior such as
105      instance allocation.)</para>
106    <para>When &CCL; first loads foreign libraries containing
107      Objective-C classes, it identifies the classes they contain. The
108      foreign class name, such as "NSWindow", is mapped to an external
109      symbol in the "NS" package via the bridge's translation rules,
110      such as NS:NS-WINDOW.  A similar transformation happens to the
111      metaclass name, with a "+" prepended, yielding something like
112      NS:+NS-WINDOW.</para>
113    <para>These classes are integrated into CLOS such that the
114      metaclass is an instance of the class OBJC:OBJC-METACLASS and
115      the class
116      is an instance of the metaclass. SLOT-DESCRIPTION metaobjects are
117      created for each instance variable, and the class and metaclass go
118      through something very similar to the "standard" CLOS class
119      initialization protocol (with a difference being that these classes
120      have already been allocated.)</para>
121    <para>Performing all this initialization, which is done when you
122      (require "COCOA"), currently takes several
123      seconds; it could conceivably be sped up some, but it's never likely
124      to be fast.</para>
125    <para>When the process is complete, CLOS is aware of several hundred
126      new Objective-C classes and their metaclasses. &CCL;'s runtime system can
127      reliably recognize MACPTRs to Objective-C classes as being CLASS objects, and
128      can (fairly reliably but heuristically) recognize instances of those
129      classes (though there are complicating factors here; see below.)
130      SLOT-VALUE can be used to access (and, with care, set) instance
131      variables in Objective-C instances. To see this, do:</para>
132    <programlisting>
133      ? (require "COCOA")
134    </programlisting>
135    <para>and, after waiting a bit longer for a Cocoa listener window to
136      appear, activate that Cocoa listener and do:</para>
137    <programlisting>? (describe (ccl::send ccl::*NSApp* 'key-window))
138    </programlisting>
139    <para>This sends a message asking for the key window, which is the window
140      that has the input focus (often the frontmost), and then describes
141      it. As we can see, NS:NS-WINDOWs have lots of interesting slots.</para>
142  </sect1>
143
144  <!-- ============================================================ -->
145  <sect1 id="Instantiating-Objective-C-Objects">
146    <title>Instantiating Objective-C Objects</title>
147    <para>Making an instance of an Objective-C class (whether the class in
148      question is predefined or defined by the application) involves
149      calling MAKE-INSTANCE with the class and a set of initargs as
150      arguments.  As with STANDARD-CLASS, making an instance involves
151      initializing (with INITIALIZE-INSTANCE) an object allocated with
152      ALLOCATE-INSTANCE.</para>
153    <para>For example, you can create an ns:ns-number like this:</para>
154    <programlisting>
155      ? (make-instance 'ns:ns-number :init-with-int 42)
156      #&lt;NS-CF-NUMBER 42 (#x85962210)>
157    </programlisting>
158    <para>It's worth looking at how this would be done if you were
159      writing in Objective C:</para>
160    <programlisting>
161      [[NSNumber alloc] initWithInt: 42]
162    </programlisting>
163    <para>Allocating an instance of an Objective-C class involves sending the
164      class an "alloc" message, and then using those initargs that
165      <emphasis>don't</emphasis> correspond to slot initargs as the
166      "init" message to be sent to the newly-allocated instance.  So, the
167      example above could have been done more verbosely as:</para>
168    <programlisting>
169      ? (defvar *n* (ccl::send (find-class 'ns:ns-number) 'alloc))
170      *N*
171
172      ? (setq *n* (ccl::send *n* :init-with-int 42))
173      #&lt;NS-CF-NUMBER 42 (#x16D340)>
174    </programlisting>
175    <para>That setq is important; this is a case where init
176      decides to replace the object and return the new one, instead
177      of modifying the existing one.
178      In fact, if you leave out the setq and
179      then try to view the value of *N*, &CCL; will freeze.  There's
180      little reason to ever do it this way; this is just to show
181      what's going on.</para>
182    <para>You've seen that an Objective-C initialization method doesn't have to
183      return the same object it was passed.  In fact, it doesn't have
184      to return any object at all; in this case, the initialization fails
185      and make-instance returns nil.</para>
186    <para>In some special cases, such as loading an ns:ns-window-controller
187      from a .nib file, it may be necessary for you to pass the
188      instance itself as one of the parameters to the initialization
189      method.  It goes like this:</para>
190    <programlisting>
191      ? (defvar *controller*
192      (make-instance 'ns:ns-window-controller))
193      *CONTROLLER*
194
195      ? (setq *controller*
196      (ccl::send *controller*
197      :init-with-window-nib-name #@"DataWindow"
198      :owner *controller*))
199      #&lt;NS-WINDOW-CONTROLLER &lt;NSWindowController: 0x1fb520> (#x1FB520)>
200    </programlisting>
201    <para>This example calls (make-instance) with no initargs.  When you
202      do this, the object is only allocated, and not initialized.  It
203      then sends the "init" message to do the initialization by hand.</para>
204
205    <para>There is an alternative API for instantiating Objective-C
206      classes. You can
207      call <literal>OBJC:MAKE-OBJC-INSTANCE</literal>, passing it the
208      name of the Objective-C class as a string. In previous
209      releases, <literal>OBJC:MAKE-OBJC-INSTANCE</literal> could be
210      more efficient than <literal>OBJC:MAKE-INSTANCE</literal> in
211      cases where the class did not define any Lisp slots; this is no
212      longer the case. You can now
213      regard <literal>OBJC:MAKE-OBJC-INSTANCE</literal> as completely
214      equivalent to <literal>OBJC:MAKE-INSTANCE</literal>, except that
215      you can pass a string for the classname, which may be convenient
216      in the case that the classname is in some way unusual.</para>
217  </sect1>
218
219  <!-- ============================================================ -->
220  <sect1 id="Calling-Objective-C-Methods">
221    <title>Calling Objective-C Methods</title>
222    <para>In Objective-C, methods are called "messages", and there's
223      a special syntax to send a message to an object:</para>
224    <programlisting>
225      [w alphaValue]
226      [w setAlphaValue: 0.5]
227      [v mouse: p inRect: r]
228    </programlisting>
229    <para>The first line sends the method "alphaValue" to the object
230      <literal>w</literal>, with no parameters.  The second line sends
231      the method "setAlphaValue", with the parameter 0.5.  The third
232      line sends the method "mouse:inRect:" - yes, all one long word -
233      with the parameters <literal>p</literal> and
234      <literal>r</literal>.</para>
235    <para>In Lisp, these same three lines are:</para>
236    <programlisting>
237      (send w 'alpha-value)
238      (send w :set-alpha-value 0.5)
239      (send v :mouse p :in-rect r)
240    </programlisting>
241    <para>Notice that when a method has no parameters, its name is an ordinary
242      symbol (it doesn't matter what package the symbol is in, as
243      only its name is checked).  When a method has parameters,
244      each part of its name is a keyword, and the keywords alternate
245      with the values.</para>
246    <para>These two lines break those rules, and both  will
247      result in error messages:</para>
248    <programlisting>
249      (send w :alpha-value)
250      (send w 'set-alpha-value 0.5)
251    </programlisting>
252    <para>Instead of (send), you can also invoke (send-super), with the
253      same interface.  It has roughly the same purpose as CLOS's
254      (call-next-method); when you use (send-super), the message is
255      handled by the superclass.  This can be used to get at the
256      original implementation of a method when it is shadowed by a
257      method in your subclass.</para>
258
259    <sect2 id="Type-Coercion-for-ObjC-Method-Calls">
260          <title>Type Coercion for Objective-C Method Calls</title>
261      <para>&CCL;'s FFI handles many common conversions between
262        Lisp and foreign data, such as unboxing floating-point args
263        and boxing floating-point results.  The bridge adds a few more
264        automatic conversions:</para>
265      <para>NIL is equivalent to (%NULL-PTR) for any message
266        argument that requires a pointer.</para>
267      <para>T/NIL are equivalent to #$YES/#$NO for any boolean argument.</para>
268      <para>A #$YES/#$NO returned by any method that returns BOOL
269        will be automatically converted to T/NIL.</para>
270    </sect2>
271
272    <sect2 id="Methods-which-Return-Structures">
273          <title>Methods which Return Structures</title>
274      <para>Some Cocoa methods return small structures, such as
275        those used to represent points, rects, sizes and ranges. When
276        writing in Objective C, the compiler hides the implementation
277        details.  Unfortunately, in Lisp we must be slightly more
278        aware of them.</para>
279      <para>Methods which return structures are called in a special
280        way; the caller allocates space for the result, and passes a
281        pointer to it as an extra argument to the method.  This is
282        called a Structure Return, or STRET.  Don't look at me; I
283        don't name these things.</para>
284      <para>Here's a simple use of this in Objective C.  The first line
285            sends the "bounds" message to v1, which returns a rectangle.
286            The second line sends the "setBounds" message to v2, passing
287            that same rectangle as a parameter.</para>
288      <programlisting>
289        NSRect r = [v1 bounds];
290        [v2 setBounds r];
291          </programlisting>
292      <para>In Lisp, we must explicitly allocate the memory, which
293        is done most easily and safely with <xref linkend="m_rlet"/>.
294        We do it like this:</para>
295      <programlisting>
296(rlet ((r :&lt;NSR&gt;ect))
297          (send/stret r v1 'bounds)
298          (send v2 :set-bounds r))
299      </programlisting>
300      <para>The rlet allocates the storage (but doesn't initialize
301        it), and makes sure that it will be deallocated when we're
302        done.  It binds the variable r to refer to it.  The call to
303        <literal>send/stret</literal> is just like an ordinary call to
304        <literal>send</literal>, except that r is passed as an extra,
305        first parameter.  The third line, which calls
306        <literal>send</literal>, does not need to do anything special,
307        because there's nothing complicated about passing a structure
308        as a parameter.</para>
309          <para>In order to make STRETs easier to use, the bridge
310            provides two conveniences.</para>
311      <para>First, you can use the macros <literal>slet</literal>
312        and <literal>slet*</literal> to allocate and initialize local
313        variables to foreign structures in one step.  The example
314        above could have been written more tersely as:</para>
315      <programlisting>
316(slet ((r (send v1 'bounds)))
317      (send v2 :set-bounds r))
318          </programlisting>
319      <para>Second, when one call to <literal>send</literal> is made
320        inside another, the inner one has an implicit
321        <literal>slet</literal> around it.  So, one could in fact
322        just write:</para>
323      <programlisting>
324(send v1 :set-bounds (send v2 'bounds))
325      </programlisting>
326      <para>There are also several pseudo-functions provided for convenience
327        by the Objective-C compiler, to make objects of specific types. The
328        following are currently supported by the bridge: NS-MAKE-POINT,
329        NS-MAKE-RANGE, NS-MAKE-RECT, and NS-MAKE-SIZE.</para>
330      <para>These pseudo-functions can be used within an SLET initform:</para>
331      <programlisting>
332(slet ((p (ns-make-point 100.0 200.0)))
333      (send w :set-frame-origin p))
334      </programlisting>
335      <para>Or within a call to <literal>send</literal>:</para>
336      <programlisting>
337(send w :set-origin (ns-make-point 100.0 200.0))
338      </programlisting>
339      <para>However, since these aren't real functions, a call like the
340        following won't work:</para>
341      <programlisting>
342(setq p (ns-make-point 100.0 200.0))
343      </programlisting>
344      <para>To extract fields from these objects, there are also some
345        convenience macros: NS-MAX-RANGE, NS-MIN-X,
346        NS-MIN-Y, NS-MAX-X, NS-MAX-Y, NS-MID-X, NS-MID-Y,
347        NS-HEIGHT, and NS-WIDTH.</para>
348      <para>Note that there is also a <literal>send-super/stret</literal>
349        for use within methods.  Like <literal>send-super</literal>,
350        it ignores any shadowing methods in a subclass, and calls the
351        version of a method which belongs to its superclass.</para>
352    </sect2>
353
354    <sect2 id="Variable-Arity-Messages">
355          <title>Variable-Arity Messages</title>
356      <para>
357        There are a few messages in Cocoa which take variable numbers
358        of arguments. Perhaps the most common examples involve
359        formatted strings:</para>
360      <programlisting>
361[NSClass stringWithFormat: "%f %f" x y]
362      </programlisting>
363      <para>In Lisp, this would be written:</para>
364      <programlisting>
365(send (find-class 'ns:ns-string)
366      :string-with-format #@"%f %f"
367      (:double-float x :double-float y))
368      </programlisting>
369      <para>Note that it's necessary to specify the foreign types of the
370        variables (in this example, :double-float), because the
371        compiler has no general way of knowing these types.  (You
372        might think that it could parse the format string, but this
373        would only work for format strings which are not determined
374        at runtime.)</para>
375      <para>Because the Objective-C runtime system does not provide any information
376        on which messages are variable arity, they must be explicitly
377        declared. The standard variable arity messages in Cocoa are
378        predeclared by the bridge.  If you need to declare a new
379        variable arity message, use
380        (DEFINE-VARIABLE-ARITY-MESSAGE "myVariableArityMessage:").</para>
381    </sect2>
382
383    <sect2 id="Optimization">
384          <title>Optimization</title>
385      <para>The bridge works fairly hard to optimize message sends,
386        when it has enough information to do so.  There are two cases
387        when it does.  In either, a message send should be nearly as
388        efficient as when writing in Objective C.</para>
389      <para>The first case is when both the message and the
390        receiver's class are known at compile-time. In general, the
391        only way the receiver's class is known is if you declare it,
392        which you can do with either a DECLARE or a THE form.  For
393        example:</para>
394      <programlisting>
395(send (the ns:ns-window w) 'center)
396          </programlisting>
397      <para>Note that there is no way in Objective-C to name the class of a
398        class.  Thus the bridge provides a declaration, @METACLASS.
399        The type of an instance of "NSColor" is ns:ns-color.  The type
400        of the <emphasis>class</emphasis> "NSColor" is (@metaclass
401        ns:ns-color):</para>
402      <programlisting>
403(let ((c (find-class 'ns:ns-color)))
404  (declare ((ccl::@metaclass ns:ns-color) c))
405  (send c 'white-color))
406      </programlisting>
407      <para>The other case that allows optimization is when only
408        the message is known at compile-time, but its type signature
409        is unique. Of the more-than-6000 messages currently provided
410        by Cocoa, only about 50 of them have nonunique type
411        signatures.</para>
412      <para>An example of a message with a type signature that is
413        not unique is SET.  It returns VOID for NSColor, but ID for
414        NSSet.  In order to optimize sends of messages with nonunique
415        type signatures, the class of the receiver must be declared at
416        compile-time.</para>
417      <para>If the type signature is nonunique or the message is
418        unknown at compile-time, then a slower runtime call must be
419        used.</para>
420      <para>When the receiver's class is unknown, the bridge's
421        ability to optimize relies on a type-signature table which it
422        maintains.  When first loaded, the bridge initializes this
423        table by scanning every method of every Objective-C class.  When new
424        methods are defined later, the table must be updated.  This
425        happens automatically when you define methods in Lisp.  After
426        any other major change, such as loading an external framework,
427        you should rebuild the table:</para>
428      <programlisting>
429? (update-type-signatures)
430      </programlisting>
431      <para>Because <literal>send</literal> and its relatives
432        <literal>send-super</literal>, <literal>send/stret</literal>,
433        and <literal>send-super/stret</literal> are macros, they
434        cannot be <literal>funcall</literal>ed,
435        <literal>apply</literal>ed, or passed as arguments to
436        functions.</para>
437      <para>To work around this, there are function equivalents to
438        them: <literal>%send</literal>,
439        <literal>%send-super</literal>,
440        <literal>%send/stret</literal>, and
441        <literal>%send-super/stret</literal>.  However, these
442        functions should be used only when the macros will not do,
443        because they are unable to optimize.</para>
444    </sect2>
445  </sect1>
446
447  <!-- ============================================================ -->
448  <sect1 id="Defining-Objective-C-Classes">
449    <title>Defining Objective-C Classes</title>
450    <para>You can define your own foreign classes, which can then be
451      passed to foreign functions; the methods which you implement in
452      Lisp will be made available to the foreign code as
453      callbacks.</para>
454    <para>You can also define subclasses of existing classes,
455      implementing your subclass in Lisp even though the parent class
456      was in Objective C.  One such subclass is CCL::NS-LISP-STRING.
457      It is also particularly useful to make subclasses of
458      NS-WINDOW-CONTROLLER.</para>
459    <para>We can use the MOP to define new Objective-C classes, but
460      we have to do something a little funny: the :METACLASS that we'd
461      want to use in a DEFCLASS option generally doesn't exist until
462      we've created the class (recall that Objective-C classes have, for the
463      sake of argument, unique and private metaclasses.) We can sort
464      of sleaze our way around this by specifying a known Objective-C
465      metaclass object name as the value of the DEFCLASS :METACLASS
466      object; the metaclass of the root class NS:NS-OBJECT,
467      NS:+NS-OBJECT, makes a good choice. To make a subclass of
468      NS:NS-WINDOW (that, for simplicity's sake, doesn't define any
469      new slots), we could do:</para>
470    <programlisting>
471(defclass example-window (ns:ns-window)
472  ()
473  (:metaclass ns:+ns-object))
474    </programlisting>
475    <para>That'll create a new Objective-C class named EXAMPLE-WINDOW whose
476      metaclass is the class named +EXAMPLE-WINDOW. The class will be
477      an object of type OBJC:OBJC-CLASS, and the metaclass will be of
478      type OBJC:OBJC-METACLASS.  EXAMPLE-WINDOW will be a subclass of
479      NS-WINDOW.</para>
480
481    <sect2 id="Defining-classes-with-foreign-slots">
482          <title>Defining classes with foreign slots</title>
483      <para>If a slot specification in an Objective-C class
484        definition contains the keyword :FOREIGN-TYPE, the slot will
485        be a "foreign slot" (i.e. an Objective-C instance variable). Be aware
486        that it is an error to redefine an Objective-C class so that its
487        foreign slots change in any way, and &CCL; doesn't do
488        anything consistent when you try to.</para>
489      <para>The value of the :FOREIGN-TYPE initarg should be a
490        foreign type specifier. For example, if we wanted (for some
491        reason) to define a subclass of NS:NS-WINDOW that kept track
492        of the number of key events it had received (and needed an
493        instance variable to keep that information in), we could
494        say:</para>
495      <programlisting>
496(defclass key-event-counting-window (ns:ns-window)
497  ((key-event-count :foreign-type :int
498                    :initform 0
499                    :accessor window-key-event-count))
500  (:metaclass ns:+ns-object))
501      </programlisting>
502      <para>Foreign slots are always SLOT-BOUNDP, and the initform
503        above is redundant: foreign slots are initialized to binary
504        0.</para>
505    </sect2>
506
507    <sect2 id="Defining-classes-with-Lisp-slots">
508          <title>Defining classes with Lisp slots</title>
509      <para>A slot specification in an Objective-C class definition that
510        doesn't contain the :FOREIGN-TYPE initarg defines a
511        pretty-much normal lisp slot that'll happen to be associated
512        with "an instance of a foreign class". For instance:</para>
513      <programlisting>
514(defclass hemlock-buffer-string (ns:ns-string)
515  ((hemlock-buffer :type hi::hemlock-buffer
516                   :initform hi::%make-hemlock-buffer
517                   :accessor string-hemlock-buffer))
518  (:metaclass ns:+ns-object))
519          </programlisting>
520      <para>As one might expect, this has memory-management
521        implications: we have to maintain an association between a
522        MACPTR and a set of lisp objects (its slots) as long as the
523        Objective-C instance exists, and we have to ensure that the Objective-C
524        instance exists (does not have its -dealloc method called)
525        while lisp is trying to think of it as a first-class object
526        that can't be "deallocated" while it's still possible to
527        reference it. Associating one or more lisp objects with a
528        foreign instance is something that's often very useful; if you
529        were to do this "by hand", you'd have to face many of the same
530        memory-management issues.</para>
531    </sect2>
532  </sect1>
533
534  <!-- ============================================================ -->
535  <sect1 id="Defining-Objective-C-Methods">
536    <anchor id="anchor_Defining-Objective-C-Methods"/>
537    <title>Defining Objective-C Methods</title>
538    <para>In Objective-C, unlike in CLOS, every method belongs to some
539      particular class.  This is probably not a strange concept to
540      you, because C++ and Java do the same thing.  When you use Lisp
541      to define Objective-C methods, it is only possible to define methods
542      belonging to Objective-C classes which have been defined in
543      Lisp.</para>
544
545    <para>You can use either of two different macros to define methods
546      on Objective-C classes. <literal>define-objc-method</literal>
547      accepts a two-element list containing a message selector name
548      and a class name, and a body. <literal>objc:defmethod</literal>
549      superficially resembles the normal
550      CLOS <literal>defmethod</literal>, but creates methods on
551      Objective-C classes with the same restrictions as those created
552      by <literal>define-objc-method</literal>.</para>
553
554    <sect2>
555      <title>Using <literal>define-objc-method</literal></title>
556      <para>As described in the
557        section <link linkend="Calling-Objective-C-Methods">Calling
558        Objective-C Methods</link>, the names of Objective-C methods
559        are broken into pieces, each piece followed by a parameter.
560        The types of all parameters must be explicitly
561        declared.</para>
562      <para>Consider a few examples, meant to illustrate the use
563        of <literal>define-objc-method</literal>. Let us define a
564        class to use in them:</para>
565
566      <programlisting>
567(defclass data-window-controller (ns:ns-window-controller)
568  ((window :foreign-type :id :accessor window)
569   (data :initform nil :accessor data))
570  (:metaclass ns:+ns-object))
571      </programlisting>
572
573      <para>There's nothing special about this class.  It inherits from
574        <literal>ns:ns-window-controller</literal>.  It has two slots:
575        <literal>window</literal> is a foreign slot, stored in the Objective-C
576        world; and <literal>data</literal> is an ordinary slot, stored
577        in the Lisp world.</para>
578
579      <para>Here is an example of how to define a method which takes no
580        arguments:</para>
581
582      <programlisting>
583(define-objc-method ((:id get-window)
584                     data-window-controller)
585    (window self))
586      </programlisting>
587
588      <para>The return type of this method is the foreign type :id,
589        which is used for all Objective-C objects.  The name of the
590        method is
591        <literal>get-window</literal>.  The body of the method is the
592        single line <literal>(window self)</literal>.  The
593        variable <literal>self</literal> is bound, within the body, to
594        the instance that is receiving the message.  The call
595        to <literal>window</literal> uses the CLOS accessor to get the
596        value of the window field.</para>
597
598      <para>Here's an example that takes a parameter.  Notice that the
599        name of the method without a parameter was an ordinary symbol,
600        but with a parameter, it's a keyword:</para>
601
602      <programlisting>
603(define-objc-method ((:id :init-with-multiplier (:int multiplier))
604                     data-window-controller)
605  (setf (data self) (make-array 100))
606  (dotimes (i 100)
607    (setf (aref (data self) i)
608          (* i multiplier)))
609  self)
610      </programlisting>
611
612      <para>To Objective-C code that uses the class, the name of this
613        method is <literal>initWithMultiplier:</literal>.  The name of
614        the parameter is
615        <literal>multiplier</literal>, and its type
616        is <literal>:int</literal>.  The body of the method does some
617        meaningless things.  Then it returns
618        <literal>self</literal>, because this is an initialization
619        method.</para>
620
621      <para>Here's an example with more than one parameter:</para>
622
623      <programlisting>
624(define-objc-method ((:id :init-with-multiplier (:int multiplier)
625                          :and-addend (:int addend))
626                     data-window-controller)
627  (setf (data self) (make-array size))
628  (dotimes (i 100)
629    (setf (aref (data self) i)
630          (+ (* i multiplier)
631             addend)))
632  self)
633      </programlisting>
634
635      <para>To Objective-C, the name of this method is
636        <literal>initWithMultiplier:andAddend:</literal>.  Both
637        parameters are of type <literal>:int</literal>; the first is
638        named <literal>multiplier</literal>, and the second
639        is <literal>addend</literal>.  Again, the method returns
640        <literal>self</literal>.</para>
641
642      <para>Here is a method that does not return any value, a so-called
643        "void method".  Where our other methods
644        said <literal>:id</literal>, this one
645        says <literal>:void</literal> for the return type:</para>
646
647      <programlisting>
648(define-objc-method ((:void :take-action (:id sender))
649                     data-window-controller)
650  (declare (ignore sender))
651  (dotimes (i 100)
652    (setf (aref (data self) i)
653          (- (aref (data self) i)))))
654      </programlisting>
655
656      <para>This method would be called <literal>takeAction:</literal>
657        in Objective-C.  The convention for methods that are going to be
658        used as Cocoa actions is that they take one parameter, which is
659        the object responsible for triggering the action.  However, this
660        method doesn't actually need to use that parameter, so it
661        explicitly ignores it to avoid a compiler warning.  As promised,
662        the method doesn't return any value.</para>
663
664      <para>There is also an alternate syntax, illustrated here.  The
665        following two method definitions are equivalent:</para>
666
667      <programlisting>
668(define-objc-method ("applicationShouldTerminate:"
669                     "LispApplicationDelegate")
670    (:id sender :&lt;BOOL>)
671    (declare (ignore sender))
672    nil)
673 
674(define-objc-method ((:&lt;BOOL>
675                        :application-should-terminate sender)
676                       lisp-application-delegate)
677    (declare (ignore sender))
678    nil)
679      </programlisting>
680      </sect2>
681
682    <sect2>
683      <anchor id="anchor_Using-objc-defmethod"/>
684
685          <title>Using <literal>objc:defmethod</literal></title>
686
687      <para>The macro <literal>OBJC:DEFMETHOD</literal> can be used to
688        define Objective-C methods.  It looks superficially like
689        <literal>CL:DEFMETHOD</literal> in some respects.</para>
690
691      <para>Its syntax is</para>
692
693      <programlisting>
694(OBC:DEFMETHOD name-and-result-type
695               ((receiver-arg-and-class) &rest; other-args)
696      &body; body)
697      </programlisting>
698
699      <para><literal>name-and-result-type</literal> is either an
700        Objective-C message name, for methods that return a value of
701        type <literal>:ID</literal>, or a list containing an
702        Objective-C message name and a foreign type specifier for
703        methods with a different foreign result type.</para>
704
705      <para><literal>receiver-arg-and-class</literal> is a two-element
706        list whose first element is a variable name and whose second
707        element is the Lisp name of an Objective-C class or metaclass.
708        The receiver variable name can be any bindable lisp variable
709        name, but <literal>SELF</literal> might be a reasonable
710        choice.  The receiver variable is declared to be "unsettable";
711        i.e., it is an error to try to change the value of the
712        receiver in the body of the method definition.</para>
713
714      <para><literal>other-args</literal> are either variable names
715            (denoting parameters of type <literal>:ID</literal>) or
716            2-element lists whose first element is a variable name and
717            whose second element is a foreign type specifier.</para>
718
719      <para>Consider this example:</para>
720
721      <programlisting>
722(objc:defmethod (#/characterAtIndex: :unichar)
723    ((self hemlock-buffer-string) (index :&lt;NSUI&gt;nteger))
724  ...)
725      </programlisting>
726
727      <para>The method <literal>characterAtIndex:</literal>, when
728        invoked on an object of
729        class <literal>HEMLOCK-BUFFER-STRING</literal> with an
730        additional argument of
731        type <literal>:&lt;NSU&gt;integer</literal> returns a value of
732        type
733        <literal>:unichar</literal>.</para>
734
735      <para>Arguments that wind up as some pointer type other
736        than <literal>:ID</literal> (e.g. pointers, records passed by
737        value) are represented as typed foreign pointers, so that the
738        higher-level, type-checking accessors can be used on arguments
739        of
740        type <literal>:ns-rect</literal>, <literal>:ns-point</literal>,
741        and so on.</para>
742
743      <para>Within the body of methods defined
744        via <literal>OBJC:DEFMETHOD</literal>, the local function
745        <literal>CL:CALL-NEXT-METHOD</literal> is defined.  It isn't
746        quite as general as <literal>CL:CALL-NEXT-METHOD</literal> is
747        when used in a CLOS method, but it has some of the same
748        semantics.  It accepts as many arguments as are present in the
749        containing method's <literal>other-args</literal> list and
750        invokes version of the containing method that would have been
751        invoked on instances of the receiver's class's superclass with
752        the receiver and other provided arguments.  (The idiom of
753        passing the current method's arguments to the next method is
754        common enough that the <literal>CALL-NEXT-METHOD</literal> in
755        <literal>OBJC:DEFMETHODs</literal> should probably do this if
756        it receives no arguments.)</para>
757
758      <para>A method defined via <literal>OBJC:DEFMETHOD</literal>
759        that returns a structure "by value" can do so by returning a
760        record created via <literal>MAKE-GCABLE-RECORD</literal>, by
761        returning the value returned
762        via <literal>CALL-NEXT-METHOD</literal>, or by other similar
763        means. Behind the scenes, there may be a pre-allocated
764        instance of the record type (used to support native
765        structure-return conventions), and any value returned by the
766        method body will be copied to this internal record instance.
767        Within the body of a method defined
768        with <literal>OBJC:DEFMETHOD</literal> that's declared to
769        return a structure type, the local macro
770        <literal>OBJC:RETURNING-FOREIGN-STRUCT</literal> can be used
771        to access the internal structure. For example:</para>
772
773       <programlisting>
774(objc:defmethod (#/reallyTinyRectangleAtPoint: :ns-rect)
775  ((self really-tiny-view) (where :ns-point))
776  (objc:returning-foreign-struct (r)
777    (ns:init-ns-rect r (ns:ns-point-x where) (ns:ns-point-y where)
778                        single-float-epsilon single-float-epsilon)
779    r))
780       </programlisting>
781     
782       <para>If the <literal>OBJC:DEFMETHOD</literal> creates a new
783       method, then it displays a message to that effect. These
784       messages may be helpful in catching errors in the names of
785       method definitions. In addition, if
786       a <literal>OBJC:DEFMETHOD</literal> form redefines a method in
787       a way that changes its type signature, &CCL; signals a
788       continuable error.</para>
789    </sect2>
790
791    <sect2 id="Method-Redefinition-Constraints">
792          <title>Method Redefinition Constraints</title>
793      <para>Objective C was not designed, as Lisp was, with runtime
794        redefinition in mind.  So, there are a few constraints about
795        how and when you can replace the definition of an Objective C
796        method.  Currently, if you break these rules, nothing will
797        collapse, but the behavior will be confusing; so
798        don't.</para>
799      <para>Objective C methods can be redefined at runtime, but
800        their signatures shouldn't change.  That is, the types of the
801        arguments and the return type have to stay the same.  The
802        reason for this is that changing the signature changes the
803        selector which is used to call the method.</para>
804      <para>When a method has already been defined in one class, and
805        you define it in a subclass, shadowing the original method,
806        they must both have the same type signature.  There is no such
807        constraint, though, if the two classes aren't related and the
808        methods just happen to have the same name.</para>
809    </sect2>
810  </sect1>
811
812  <!-- ============================================================ -->
813  <sect1 id="Loading-Objc-Frameworks">
814    <title>Loading Frameworks</title>
815
816    <para>On Mac OS X, a framework is a structured directory
817      containing one or more shared libraries along with metadata such
818      as C and Objective-C header files. In some cases, frameworks may
819      also contain additional items such as executables.</para>
820
821    <para>Loading a framework means opening the shared libraries and
822      processing any declarations so that &CCL; can subsequently call
823      its entry points and use its data structures. &CCL; provides the
824      function <literal>OBJC:LOAD-FRAMEWORK</literal> for this
825      purpose.</para>
826
827    <programlisting>
828(OBJC:LOAD-FRAMEWORK framework-name interface-dir)
829    </programlisting>
830
831    <para><literal>framework-name</literal> is a string that names the
832    framework (for example, "Foundation", or "Cocoa"),
833    and <literal>interface-dir</literal> is a keyword that names the
834    set of interface databases associated with the named framework
835    (for example, <literal>:foundation</literal>,
836    or <literal>:cocoa</literal>).</para>
837
838    <para>Assuming that interface databases for the named frameworks
839    exist on the standard search
840    path, <literal>OBJC:LOAD-FRAMEWORK</literal> finds and initializes
841    the framework bundle by searching OS X's standard framework search
842    paths. Loading the named framework may create new Objective-C
843    classes and methods, add foreign type descriptions and entry
844    points, and adjust &CCL;'s dispatch functions.</para>
845
846    <para>If interface databases don't exist for a framework you want
847    to use, you will need to create them. For more information about
848    creating interface databases,
849    see <link linkend="Creating-new-interface-directories">Creating
850    new interface directories</link>.</para>
851  </sect1>
852
853  <!-- ============================================================ -->
854  <sect1 id="How-Objective-C-Names-are-Mapped-to-Lisp-Symbols">
855    <title>How Objective-C Names are Mapped to Lisp Symbols</title>
856    <para>There is a standard set of naming conventions for Cocoa
857      classes, messages, etc.  As long as they are followed, the
858      bridge is fairly good at automatically translating between Objective-C
859      and Lisp names.</para>
860    <para>For example, "NSOpenGLView" becomes ns:ns-opengl-view;
861      "NSURLHandleClient" becomes ns:ns-url-handle-client; and
862      "nextEventMatchingMask:untilDate:inMode:dequeue:" becomes
863      (:next-event-matching-mask :until-date :in-mode :dequeue).  What
864      a mouthful.</para>
865    <para>To see how a given Objective-C or Lisp name will be translated by
866      the bridge, you can use the following functions:</para>
867        <simplelist type="vert">
868          <member>(ccl::objc-to-lisp-classname string)</member>
869          <member>(ccl::lisp-to-objc-classname symbol)</member>
870          <member>(ccl::objc-to-lisp-message string)</member>
871          <member>(ccl::lisp-to-objc-message string)</member>
872          <member>(ccl::objc-to-lisp-init string)</member>
873          <member>(ccl::lisp-to-objc-init keyword-list)</member>
874        </simplelist>
875
876    <para>Of course, there will always be exceptions to any naming
877      convention.  Please tell us on the mailing lists if you come
878      across any name translation problems that seem to be bugs.
879      Otherwise, the bridge provides two ways of dealing with
880      exceptions:</para>
881    <para>First, you can pass a string as the class name of
882      MAKE-OBJC-INSTANCE and as the message to SEND.  These strings
883      will be directly interpreted as Objective-C names, with no
884      translation. This is useful for a one-time exception.  For
885      example:</para>
886    <programlisting>
887(ccl::make-objc-instance "WiErDclass")
888(ccl::send o "WiErDmEsSaGe:WithARG:" x y)
889    </programlisting>
890    <para>Alternatively, you can define a special translation rule
891      for your exception.  This is useful for an exceptional name that
892      you need to use throughout your code.  Some examples:</para>
893    <programlisting>
894(ccl::define-classname-translation "WiErDclass" wierd-class)
895(ccl::define-message-translation "WiErDmEsSaGe:WithARG:" (:weird-message :with-arg))
896(ccl::define-init-translation "WiErDiNiT:WITHOPTION:" (:weird-init :option))
897    </programlisting>
898    <para>The normal rule in Objective-C names is that each word begins with a
899      capital letter (except possibly the first).  Using this rule
900      literally, "NSWindow" would be translated as N-S-WINDOW, which
901      seems wrong.  "NS" is a special word in Objective-C that should not be
902      broken at each capital letter. Likewise "URL", "PDF", "OpenGL",
903      etc. Most common special words used in Cocoa are already defined
904      in the bridge, but you can define new ones as follows:</para>
905    <programlisting>
906(ccl::define-special-objc-word "QuickDraw")
907    </programlisting>
908    <para>Note that message keywords in a SEND such as (SEND V
909      :MOUSE P :IN-RECT R) may look like the keyword arguments in a
910      Lisp function call, but they really aren't. All keywords must be
911      present and the order is significant. Neither (:IN-RECT :MOUSE)
912      nor (:MOUSE) translate to "mouse:inRect:"</para>
913    <para>Also, as a special exception, an "init" prefix is optional
914      in the initializer keywords, so (MAKE-OBJC-INSTANCE 'NS-NUMBER
915      :INIT-WITH-FLOAT 2.7) can also be expressed as
916      (MAKE-OBJC-INSTANCE 'NS-NUMBER :WITH-FLOAT 2.7)</para>
917  </sect1>
918</chapter>
Note: See TracBrowser for help on using the repository browser.