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

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

added discussion of objc:defmethod and made some edits of existing docs for define-objc-method

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