source: project/wiki/eggref/4/objc @ 25526

Last change on this file since 25526 was 25526, checked in by Jim Ursetto, 9 years ago

wiki/objc: Stress incompatibility with 10.6 or higher

File size: 29.3 KB
Line 
1[[tags:eggs]]
2
3== Objc
4
5This is version 0.5 of the '''objc''' extension library for Chicken Scheme.
6
7[[toc:]]
8
9== Description
10
11
12Scheme to Objective C bridge
13
14== Documentation
15
16
17This egg provides a basic interface to Objective C from Scheme.  You can invoke class and instance methods, access instance variables, and define Objective C classes directly in Scheme.
18
19This egg [[#Requirements|requires Mac OS X 10.5 ''or earlier'', and libffi]].
20
21=== Method invocation
22
23
24<macro>(objc:send RECEIVER KEYWORD1 ARGUMENT1 ...)</macro><br>
25
26Sends the message KEYWORD1 ARGUMENT1 ... to RECEIVER, which is an {{objc:instance}} or {{objc:class}} object.  This follows the normal Objective C syntax, so the call {{(objc:send myRect setWidth: 15.0 height: 20.0)}} invokes the method {{setWidth:height:}} on myRect, with arguments 15.0 and 20.0.  If the method has no arguments, use a symbol instead of a keyword: {{(objc:send NSScanner alloc)}}.
27
28
29
30<macro>(objc:send/safe RECEIVER KEYWORD1 ARGUMENT1 ...)</macro><br>
31
32Identical to {{(objc:send RECEIVER KEYWORD1 ARGUMENT1 ...)}}, but allows callbacks from Objective C into Scheme.  Safe calls are required when invoking any Objective C method that is either implemented in Scheme, or could itself invoke a method defined in Scheme.
33
34<macro>(objc:send/maybe-safe RECEIVER KEYWORD1 ARGUMENT1 ...)</macro><br>
35<parameter>(objc:optimize-callbacks) [default: #t]</parameter><br>
36
37Identical to {{objc:send/safe}} when the object or class (or any superclass) is implemented in Scheme, and to {{objc:send}} otherwise.  In general, this greatly improves invocation time for pure Objective C classes and objects, has a negligible impact on Scheme classes, and incurs a 10% penalty for Scheme instances.  This optimization can be disabled by setting the parameter {{objc:optimize-callbacks}} to {{#f}}---in which case a safe call will always be used.
38
39<macro>(@ RECEIVER KEYWORD ARGUMENT ...)</macro><br>
40
41An abbreviation for {{(objc:send/maybe-safe RECEIVER KEYWORD ARGUMENT ...)}}.  The older {{@[...]}} form is deprecated.
42
43For enhanced readability, the bridge accepts hyphenated selector keywords and translates them into their Objective C counterparts by uppercasing any character after a hyphen, then removing the hyphens.  For example, the following are equivalent:
44
45 (@ NSDictionary dictionary-with-contents-of-file: name)
46 (@ NSDictionary dictionaryWithContentsOfFile: name)
47
48<read>@[RECEIVER KEYWORD ARGUMENT ...]</read><br>
49
50Same as {{objc:send/maybe-safe}}.  If the receiver is prefixed with the {{unsafe:}} keyword, then this form expands into a {{(objc:send ...)}} expression instead.  Prefixing with {{safe:}} guarantees an {{objc:send/safe}} call.
51
52This form is deprecated in favor of {{(@ ...)}}.
53
54=== Instances
55
56
57<record>objc:instance</record><br>
58
59A wrapper for an instance of an Objective C class.  The object's {{description}} method determines how this record is displayed.
60
61
62
63<procedure>(objc:class-of ID)</procedure><br>
64
65Return the class of objc:instance ID, obtained by sending ID a class message.  This procedure also accepts a class object, but the result will generally be the same object.
66
67
68
69<procedure>(objc:instance->pointer OBJ)</procedure><br>
70
71Return the raw pointer associated with objc:instance OBJ.
72
73
74
75<procedure>(objc:pointer->instance ptr)</procedure><br>
76
77Create an objc:instance from a raw instance pointer (an {{id}}).  Implicitly retains the object, releasing it when the objc:instance is finalized.
78
79
80
81=== Strings
82
83
84<procedure>(objc:nsstring STRING)</procedure><br>
85
86Constructs a new NSString from STRING.  Currently assumes UTF8 encoding.
87
88
89
90<read>@"..."</read><br>
91
92Equivalent to {{(objc:nsstring "...")}}.
93
94
95
96<procedure>(objc:nsstring->string STRING)</procedure><br>
97
98Converts an NSString into a Scheme string.
99
100
101
102=== Instance variables
103
104
105<procedure>(objc:ivar-ref OBJECT NAME)</procedure><br>
106
107Returns the value of OBJECT's instance variable NAME (which should be a string).
108
109[[#type-conversions|Type conversion]] is performed on the result, based on the ivar's type.  When the ivar refers to a Scheme object (i.e., is a [[#type-qualifiers|{{#:slot}} or {{#:wrapper}})]], the object is returned transparently.
110
111
112
113<procedure>(objc:ivar-set! OBJECT NAME VALUE)</procedure><br>
114
115Sets the value of OBJECT's instance variable NAME to VALUE.
116
117Type conversion is performed on VALUE, based on the ivar type.  When the ivar is a {{#:slot}} or a {{#:wrapper}},  VALUE can be any Scheme object.
118
119[[#memory-management|Reference counts are automatically managed]] for {{id}} types.
120
121A SRFI-17 setter is also provided, in the form
122
123 (set! (objc:ivar-ref OBJECT NAME) VALUE)
124
125<macro>(ivar-ref OBJECT NAME)</macro><br>
126
127Shorthand for {{(objc:ivar-ref OBJECT (symbol->string NAME))}}.
128
129
130
131<macro>(ivar-set! OBJECT NAME VALUE)</macro><br>
132
133Shorthand for {{(objc:ivar-set! OBJECT (symbol->string NAME) VALUE)}}.
134
135
136
137<read>@VAR</read><br>
138
139Intended for use within methods, this expands to {{(objc:ivar-ref self "VAR")}}.
140
141Use {{(set! @var value)}} to set an instance variable.
142
143
144 Examples: 
145 (objc:ivar-set! p "x" 3) 
146 (objc:ivar-ref p "x")     ; => 3 
147 (ivar-ref p x)            ; => 3   
148 (set! @x (vector 1 2 3))  ; when @x is a slot: 
149 @x                        ; => #(1 2 3)
150
151=== Classes
152
153
154<macro>(define-objc-classes NAME ...)</macro><br>
155
156Locates the Objective C classes NAME ... and defines variables holding pointers to the class objects. NAME may be a symbol or a list of the form {{(VARIABLE CLASSNAME)}}. For example, {{(define-objc-classes NSTextView NSTask)}} is equivalent to
157
158 (begin
159   (define NSTextView (objc:string->class "NSTextView"))
160   (define NSTask (objc:string->class "NSTask")))
161
162<record>objc:class</record><br>
163
164A record representing an Objective C class.
165
166<table class="symbol-table"><tr><td>name</td><td>Class name as a string.</td></tr>
167<tr><td>method-list</td><td>List of instance methods.  The format is {{((NAME . SIGNATURE) ...)}}, but may change in the future to a list of objc:method records.</td></tr>
168<tr><td>class-method-list</td><td>List of class methods.</td></tr>
169<tr><td>super-class</td><td>Superclass of this class (as an objc:class).</td></tr>
170<tr><td>meta-class</td><td>Metaclass of this class (as an objc:class).</td></tr>
171<tr><td>ivar-list</td><td>List of all instance variables in this class (as objc:raw-ivar records).</td></tr>
172<tr><td>ivars</td><td>List of ivars in this class defined in Scheme (as objc:ivar records).</td></tr>
173<tr><td>all-ivars</td><td>Aggregate list of objc:ivar records from the class hierarchy.</td></tr>
174</table>
175
176A note on instance variables: the bridge generates {{objc:ivar}} records only for ivars defined in Scheme.  However, {{objc:raw-ivar}} records are available for all instance variables.  This API ({{ivar-list / ivars / all-ivars}}) is new and subject to change.
177
178
179
180<procedure>(objc:class->pointer CLASS)</procedure><br>
181
182Return the raw pointer associated with objc:class CLASS.
183
184
185
186<procedure>(objc:pointer->class ptr)</procedure><br>
187
188Create a class from a raw class pointer (a {{Class}}).
189
190
191
192<procedure>(objc:string->class STRING)</procedure><br>
193
194Look up and return the Objective C class named STRING.
195
196
197
198<macro>(objc:define-method CLASS RT ARGS . BODY)</macro><br>
199<macro>(objc:define-class-method CLASS RT ARGS . BODY)</macro><br>
200
201Define an instance or class method in CLASS.
202
203<table class="symbol-table"><tr><td>CLASS</td><td>An objc:class object representing the destination class.</td></tr>
204<tr><td>RT</td><td>The return type of the method.</td></tr>
205<tr><td>ARGS</td><td>{{((KEYWORD TYPE VAR-NAME) ...)}} or {{SYMBOL}}</td></tr>
206<tr><td>BODY</td><td>Body of a lambda comprising the method.  The parameters visible inside the lambda are self (a class or instance object), sel (the method selector), and the arguments given in ARGS.</td></tr>
207</table>
208
209Each list in ARGS adds a method argument of type TYPE, visible to the method body as VAR-NAME.  As in Objective C, each argument is associated with a KEYWORD and each KEYWORD is combined into a method name.  Hyphenated keywords are accepted, just like in method invocations.  A bare SYMBOL can be used as the method name (instead of a list) if no arguments are expected.
210
211TYPE should be a [[#types|short typename]], a symbol such as {{INT}}.
212
213Within a method body, you can use {{(@ super ...)}} to call a class or instance method of the superclass.  Note: {{super}} is a reserved keyword, not a variable.
214
215Example:
216 
217  (objc:define-method Rect VOID ((set-width: DBL my-w)
218                                 (height:    DBL my-h))
219    (ivar-set! self w my-w)
220    (ivar-set! self h my-h))
221
222Method removal is not yet implemented, but redefining a method will override the old definition.
223
224
225
226<macro>(define-objc-class CLASS SUPERCLASS IVARS . METHODS)</macro><br>
227
228Defines CLASS (a symbol) with superclass SUPERCLASS (a symbol), instance variables IVARS, and methods METHODS.  The new classname is imported with {{define-objc-classes}}.
229
230SUPERCLASS is looked up for you in the runtime, so it need not be imported.
231
232IVARS is a list of the form {{((TYPE NAME) ...)}}, where TYPE is a [[#type-qualifiers|type qualifier]] and NAME is a symbol representing the new variable name.  Each instance of CLASS will have a separate copy of these variables.
233
234METHODS are method definitions of the form {{(define-[class-]method RT ARGS . BODY)}}, which are equivalent to calling {{(objc:define-[class]-method CLASS RT ARGS . BODY)}} using the current CLASS.  These methods are defined in the lexical environment of the surrounding {{define-objc-class}} expression.  As a simple consequence, you can surround the class definition with a {{let}} statement and create "static" variables for the class.
235
236You can also use '''+''' as an alias for {{define-class-method}} and '''-''' for {{define-method}}.  These correspond to Objective C method definition syntax.
237 Example:
238 
239  (define-objc-class MyPoint NSObject ((DBL x)
240                                       (DBL y) 
241                                       (slot: closure))
242    (define-method ID init
243      (print "MyPoint init")
244      (@ super init))
245    (- DBL getX @x)
246    (- DBL getY @y)
247    (- ID description
248       (sprintf "<MyPoint: (~a, ~a)>" @x @y))
249 
250    (- VOID ((move-by-x: DBL a) (y: DBL b))
251      (set! @x (+ a @x))
252      (ivar-set! self y (+ b (ivar-ref self y))))  ;; more wordy
253 
254    (- ID ((init-with-x: DBL a) (y: DBL b))
255       (let ((p (@ self init)))
256         (@ p move-by-x: a y: b)
257         (set! @closure (lambda (msg)
258                          (cond ((eq? msg 'initial-x) 
259                                 (print "MyPoint: initial x was " a))
260                                ((eq? msg 'initial-y) 
261                                 (print "MyPoint: initial y was " b)))))
262         p)))
263 
264  #;1> (define p (@ (@ MyPoint alloc) init-with-x: 3.4 y: 4.5))
265  MyPoint init
266  #;2> (@ p move-by-x: 2 y: 3)
267  #<objc-instance <MyPoint: (5.4, 7.5)>>
268  #;3> ((ivar-ref p closure) 'initial-x)
269  MyPoint: initial x was 3.4
270
271
272
273<parameter>(objc:allow-class-redefinition) [default: #t]</parameter><br>
274
275If #f, an error will occur when attempting to redefine an existing class with define-objc-class.
276
277If #t, redefinition is allowed and a warning will be printed.
278
279
280
281=== Types
282
283
284Objective C is a typed language, and the bridge uses these types to decide how to pass values into and out of Objective C.  Each type is represented by a specific string and the bridge provides a variable containing each type string.  The variable names and their associated Objective C types are listed below.
285
286{{objc:define-method}} uses short versions of the types below, with the {{objc:}} prefix removed.  For example, use {{ID}} instead of {{objc:ID}}. The full names are generally used for lower-level methods such as {{objc:add-method}} and {{objc:set-ivars!}}.
287
288<table class="symbol-table"><tr><td>objc:ID</td><td>id</td></tr>
289<tr><td>objc:CLASS</td><td>Class</td></tr>
290<tr><td>objc:SEL</td><td>SEL</td></tr>
291<tr><td>objc:INT</td><td>int</td></tr>
292<tr><td>objc:DBL</td><td>double</td></tr>
293<tr><td>objc:FLT</td><td>float</td></tr>
294<tr><td>objc:CHR</td><td>char</td></tr>
295<tr><td>objc:SHT</td><td>short</td></tr>
296<tr><td>objc:LNG</td><td>long</td></tr>
297<tr><td>objc:USHT</td><td>unsigned short</td></tr>
298<tr><td>objc:UINT</td><td>unsigned int</td></tr>
299<tr><td>objc:UCHR</td><td>unsigned char</td></tr>
300<tr><td>objc:ULNG</td><td>unsigned long</td></tr>
301<tr><td>objc:BOOL</td><td>BOOL</td></tr>
302<tr><td>objc:PTR</td><td>void *</td></tr>
303<tr><td>objc:CHARPTR</td><td>char *</td></tr>
304<tr><td>objc:NSRECT</td><td>NSRect</td></tr>
305<tr><td>objc:NSSIZE</td><td>NSSize</td></tr>
306<tr><td>objc:NSPOINT</td><td>NSPoint</td></tr>
307<tr><td>objc:NSRANGE</td><td>NSRange</td></tr>
308<tr><td>objc:VOID</td><td>void</td></tr>
309</table>
310
311Instance variables defined in {{define-objc-class}} use the type qualifiers in the following table.
312
313<table class="symbol-table"><tr><td>DBL, INT, etc.</td><td>An {{objc:DBL}}, {{objc:INT}}, etc. type---use short typenames, as in {{objc:define-method}}.</td></tr>
314<tr><td>ID</td><td>An Objective C instance (objc:ID) with automatic [[#memory-management|memory management]].</td></tr>
315<tr><td>#:outlet</td><td>An Interface Builder outlet (objc:ID).  Memory management is not performed.</td></tr>
316<tr><td>#:slot</td><td>Holds a scheme object, such as a vector or closure.</td></tr>
317<tr><td>#:wrapper</td><td>Holds a scheme object like #:slot, but is less efficient.</td></tr>
318</table>
319
320=== Type conversions
321
322
323Numeric types (such as double and int) are converted to and from Scheme numbers just as in Chicken's C FFI.
324
325Class types are wrapped in unique objc:class records when passed to Scheme---see [[#class-proxies|Class Proxies]] for more details.
326
327An {{id}}, or instance, type is almost always represented as an {{objc:instance}} record, which is a thin wrapper around a pointer to the Objective C object.  There is generally no automatic conversion to or from Scheme objects, even when the object has a reasonable direct representation in Scheme.  For example, you may not pass the number "3" to a method expecting an {{id}}, even though "3" could be represented as an {{NSNumber}}.  Conversely, an NSNumber representing "3" remains an {{objc:instance}} when returned to Scheme.
328
329There is one exception to this rule: you may pass a string to any method which expects an {{id}}, and it will become an {{NSString}}.  Of course, you can always perform conversions manually using Objective C methods---continuing the example above, an {{(@ NSNumber number-with-int: 3)}} can indeed be passed as an {{id}} argument.  The author has written convenience functions for NSNumber, NSDictionary, and NSArray which reduce the drudgery of conversion.  These should be available soon; [[http://3e8.org/zb|check here for updates]].
330
331Objective C lacks a boolean type; booleans are char types where zero is false and non-zero is true.  Since (char)0 is rare, we convert it to #f when passed to Scheme, which allows Scheme predicates to work without a special test.  We also transform #t and #f to (char)1 and (char)0 when passed to Objective C.  Other character values are passed through as-is.  Unsigned char values, on the other hand, never represent booleans and aren't transformed.
332
333Selectors are converted to strings when passed to Scheme, and strings converted back to selectors when passed to Objective C.  Note that selectors may be wrapped in objc:selector objects in the future.
334
335CHARPTR (char *) types are converted to Scheme strings, but conversion to CHARPTR is disabled.
336
337NSRect, NSPoint, NSSize and NSRange structures can be sent to and received from Objective C.  Each is represented by a record on the Scheme side.
338
339<record>ns:rect</record><br>
340
341{{ns:make-rect}} is provided as an alias for the default constructor {{make-ns:rect}}.  The same is true for the other records.
342
343<table class="symbol-table"><tr><td>x</td><td>X coordinate of origin (NSRect.origin.x)</td></tr>
344<tr><td>y</td><td>Y coordinate of origin (NSRect.origin.y)</td></tr>
345<tr><td>width</td><td>Width of rectangle (NSRect.size.width)</td></tr>
346<tr><td>height</td><td>Height of rectangle (NSRect.size.height)</td></tr>
347</table>
348
349
350
351<record>ns:size</record><br>
352
353<table class="symbol-table"><tr><td>width</td><td>Width</td></tr>
354<tr><td>height</td><td>Height</td></tr>
355</table>
356
357
358
359<record>ns:point</record><br>
360
361<table class="symbol-table"><tr><td>x</td><td>X coordinate</td></tr>
362<tr><td>y</td><td>Y coordinate</td></tr>
363</table>
364
365
366
367<record>ns:range</record><br>
368
369<table class="symbol-table"><tr><td>location</td><td>Start index, 0-based</td></tr>
370<tr><td>length</td><td>Length of range</td></tr>
371</table>
372
373
374
375Other than the four exceptions above, struct, union, and array types cannot be sent to or received from Objective C.
376
377=== Memory management
378
379
380The bridge strives to handle memory management automatically.  In general terms, this is accomplished by implicitly retaining an instance object when it is passed into Scheme, and releasing it when the objc:instance is finalized.  The bridge knows that certain selectors, such as alloc and copy, by convention donate a retain reference to you, and adjusts its retain count accordingly.  Furthermore, passing an objc:instance into Objective C retains and autoreleases that object, which is necessary to ensure that short-lived objects (such as automatically created strings) remain valid until the end of a method invocation.  (Each invocation is wrapped in an autorelease pool, hence the autorelease.)
381
382In general, this means you don't have to worry about releasing, autoreleasing or retaining objects.  The expression {{(let ((m [@ MyPoint alloc])) (void))}}, for example, incurs no memory penalty as {{m}} is garbage collected like any other Scheme object.  This principle extends to NSStrings that are created by the bridge when converted from Scheme strings.  Additionally, you may return newly allocated objects from Scheme classes without autoreleasing them.
383
384Instance variables which hold Objective C objects---'''id''' types---are also managed automatically.  Those defined in a Scheme class are properly retained when using {{objc:ivar-set!}}, and properly released in {{dealloc}}.  You should use the {{#:outlet}} type qualifier for Interface Builder outlets, which will turn off automatic management as IB expects.  Ivars defined in a pure Objective C class are never retained or released automatically, as these classes expect to manage memory themselves.  If you must access such a variable directly, you must manually send it retain and release messages (editor's note: the API for such is not exposed right now).
385
386There are some limitations.  Overriding memory-management selectors such as alloc, release, and dealloc is not supported (although alloc does appear to work fine, caveat emptor).  Sending an autorelease message has no effect due to the current implementation of method invocation.  Finally, although the author has tried to ensure automatic memory management works as advertised, certain cases (especially involving calls from Objective C to Scheme) have not been tested and may be problematic at this point.
387
388=== Class proxies
389
390
391In order to implement ivar memory management and transparent access to Scheme objects stored in ivars, the bridge needs to maintain metadata for each class defined in Scheme.  Enter the class proxy, a unique {{objc:class}} record for each class.  Whenever a class pointer is passed into Scheme, this corresponding proxy is looked up and returned.  This means that Scheme can store information about classes beyond that available in the Objective C runtime.
392
393For pure Objective C classes, this proxy is generic, and springs into being dynamically the first time the class is referenced.  It doesn't contain any extra data; it simply notes the class is pure Objective C.
394
395For classes defined in Scheme, the proxy is created at class definition time, and contains (amongst other things) extended instance variable data, including type qualifiers such as slot: and outlet:.  {{objc:ivar-set!}} will look up the object's class, find the appropriate ivar and notice any type qualifier.  Class proxies also keep track of which classes have Scheme implementations, used for minimizing safe callbacks.
396
397Instance proxies per se are not (yet) implemented.  Although objects are wrapped in objc:instance records, each is merely a non-unique wrapper around a pointer and contains no extra data.  Of course, since instance variables can hold Scheme objects, you can store as many "proxy" objects as you like inside any instance.  On the other hand, you have to manually access this data via ivar-ref or by sending the Objective C object a message, which can be cumbersome.  In practice, it may be useful to do this transparently, having an interchangeable proxy Scheme object and Objective C instance.  This is an active area of research.
398
399=== Lowlevel
400
401
402<procedure>(objc:register-class CLASSNAME SUPERCLASS)</procedure><br>
403
404Registers CLASSNAME (a string) having superclass SUPERCLASS (an objc:class) with the Objective C runtime.  An error is raised if CLASSNAME already exists.
405
406
407
408<procedure>(objc:set-ivars! CLASS IVARS)</procedure><br>
409
410Defines in CLASS (an objc:class) the instance variables in IVARS (a list of objc:instance-var records).  The offset parameter of the instance variable records is ignored.
411
412Warning: all old instance variables in MyClass will be removed first. Also, we don't check for conflicts with superclass instance variables.  This should be remedied in a future release.
413
414 Example: 
415 (objc:set-ivars! MyClass (list (make-objc:raw-ivar "jimmy" objc:INT 0) 
416                                (make-objc:raw-ivar "cammy" objc:DBL 0)
417
418
419
420<procedure>(objc:add-method CLASS METHOD TYPES PROC)</procedure><br>
421<procedure>(objc:add-class-method CLASS METHOD TYPES PROC)</procedure><br>
422
423Adds a class or instance method to CLASS.
424
425<table class="symbol-table"><tr><td>METHOD</td><td>Method name as a string (e.g. {{"setWidth:height:"}})</td></tr>
426<tr><td>TYPES</td><td>List of encoded argument type strings (such as {{objc:INT}} or "@").</td></tr>
427<tr><td>PROC</td><td>Scheme procedure representing the method.</td></tr>
428</table>
429
430The structure of the TYPES list is {{(RETURN-TYPE SELF SELECTOR METHOD-ARGS...)}}.
431
432You may add Scheme methods to pure Objective C classes; when class proxies are enabled, this will automatically taint the class so that safe calls are used.  Currently, a warning is printed when a class is tainted.
433
434 Transformation: 
435 (objc:define-method MyClass DBL ((sel1: INT i) (sel2: DBL d)) 
436                                 (print i) (+ i d)) 
437 => 
438 (objc:add-method MyClass "sel1:sel2:"
439                  (list objc:DBL objc:ID objc:SEL objc:INT objc:DBL) 
440                  (lambda (self sel i d) (print i) (+ i d))) 
441 
442
443
444
445<procedure>(objc:wrap X)</procedure><br>
446<procedure>(objc:unwrap X)</procedure><br>
447
448Wrap or unwrap the Scheme object X inside an Objective C instance (specifically, a {{Scheme_Object_Wrapper}}) so that it can be passed as an {{id}} type.  Essentially, these functions allow you to tunnel a Scheme object through the Objective C bridge, when both endpoints are written in Scheme.  At the moment, the resulting object cannot be accessed meaningfully from the Objective C side.
449
450These functions are also used to implement the {{#:wrapper}} type qualifier for instance variables.
451
452
453
454<record>objc:raw-ivar</record><br>
455
456A record describing an Objective C instance variable as seen from the Objective C (as opposed to Scheme) side.  Returned by {{objc:class-ivar-list}}, and used by {{objc:set-ivars!}}.
457
458<table class="symbol-table"><tr><td>name</td><td>Name as a string.</td></tr>
459<tr><td>type</td><td>Type as an encoded type string.</td></tr>
460<tr><td>offset</td><td>Offset within class -- for debugging only.</td></tr>
461</table>
462
463
464
465<record>objc:ivar</record><br>
466
467A record describing Scheme's view of an Objective C instance variable.  At the moment, fields include those of {{objc:raw-ivar}} with the following addition:
468
469<table class="symbol-table"><tr><td>function</td><td>Keyword #:slot, #:wrapper, #:outlet, or #:ivar.</td></tr>
470</table>
471
472
473
474<procedure>(with-autorelease-pool THUNK)</procedure><br>
475
476Creates an autorelease pool that lasts for the duration of the thunk.
477
478A global autorelease pool is created automatically at startup, one is wrapped around the main Application Kit event loop, one is wrapped around every call to Objective C, and memory management is generally otherwise automatic.  It is considered unlikely you will have to use this, unless you send Objective C messages directly inside a foreign-lambda.
479
480
481
482<procedure>(objc:import-classes-at-toplevel!)</procedure><br>
483
484Import every class visible to the runtime, as if define-objc-classes had been run on all available classes.  Useful for debugging.  Note that some (rare) classes are not derived from NSObject, and will not respond to standard NSObject selectors, may throw exceptions, or may crash if used.
485
486
487
488<procedure>(objc:get-class-list)</procedure><br>
489
490Looks up and returns a list of all available classes.  At startup, the result of this call is stored in the variable {{objc:classes}}.
491
492
493
494== Cocoa
495
496
497{{(require-extension cocoa)}}
498
499It is possible to create Cocoa applications using this extension.  See [[http://3e8.org/zb/cocoa/creating-a-cocoa-app.html|Creating a Cocoa Application in Chicken]] for a document which walks you through implementing Apple's famous Currency Converter application.
500
501Also, a working application is included in this egg.  Untar the egg, change to the {{tests/}} directory, and type {{make}}.  An application called Temperature Converter will be built.
502
503Some [[http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/ObjC_classic/Functions/AppKitFunctions.html|global Application Kit functions]], such as NSRectFill, take structures which are passed by value.  However, the Chicken FFI only supports passing structs by pointers.  A workaround is provided in the egg; if you need to wrap such a function, see {{ns:rect-fill}} in {{cocoa.scm}} for an example.
504
505<procedure>(ns:application-main)</procedure><br>
506
507Starts the main event loop of a Cocoa-based application.  If any arguments are present on the command line, they will be passed to NSApplicationMain.
508
509
510
511<procedure>(ns:beep)</procedure><br>
512
513Plays the default system sound using NSBeep.
514
515
516
517<procedure>(ns:log FORMAT-STR ARGS...)</procedure><br>
518
519Logs a message using NSLog.  The optional {{ARGS}} are interpolated into {{FORMAT-STR}} as in {{printf}}.
520
521
522
523<procedure>(ns:rect-fill RECT)</procedure><br>
524
525Fills the passed RECT (an {{ns:rect}}) with the current color, using NSRectFill.
526
527<procedure>(cocoa:run)</procedure><br>
528
529Send the run message to the global NSApplication object.  This is intended to be used during debugging, to restart the main application event loop after an error has returned you to the REPL.
530
531== About this egg
532
533=== Requirements
534
535'''Mac OS X Intel or PPC (10.5 or earlier)'''.  This egg does not run on GNUStep.  It also does not run on OS X 10.6 or later due to significant internal changes in Objective C, and there are no plans to make it compatible.
536
537'''libffi'''.  Chicken itself need not be compiled with libffi support; libffi just needs to be installed on your system.  Install one of these:
538
539* On 10.5, libffi should already be installed.  The egg will try to use the system copy.
540* [[http://3e8.org/pub/libffi-20071207.tgz|libffi-20071207]]: Preferred build, from a recent [[http://3e8.org/pub/libffi-20071207-build.txt|SVN snapshot]].
541* [[http://www.call-with-current-continuation.org/tarballs/libffi-3.tgz|libffi-3 (Felix's build)]].  Tried and true, but may not work on Leopard.
542* [[http://sourceware.org/libffi|libffi 2.1]]: last public release of libffi, several years old.  Probably unusable.
543
544=== Author
545
546[[http://3e8.org/zb|Jim Ursetto]], [[mailto:felix@call-with-current-continuation.org|Felix Winkelmann]]
547
548=== Version history
549
550; 0.5.0 : Port to Chicken 4, with assistance from Alex Shinn.
551; 0.4.3 : Callback-safe context for {{release}}; {{add-method}} taints pure ObjC classes.  Verify egg on x86.
552; 0.4 : Class proxies, ivar refcounting, ivar Scheme objects, objc:wrap/unwrap, (@ ...) syntax, hyphenated selectors, callback optimization. [[http://3e8.org/zb/eggs/objc-04-changes.txt|Detailed changelog.]]
553; 0.3 : Enable struct support; change to ns: prefix.
554; 0.2 : Add objc:class-of and rename extension
555; 0.1 : Initial release
556
557=== License
558
559 Copyright (c) 2005, 2006, 2007, 2008, 2009, 2010 Jim Ursetto.
560 All rights reserved.
561 
562 Redistribution and use in source and binary forms, with or without
563 modification, are permitted provided that the following conditions are met:
564 
565   Redistributions of source code must retain the above copyright notice,
566   this list of conditions and the following disclaimer. Redistributions in
567   binary form must reproduce the above copyright notice, this list of
568   conditions and the following disclaimer in the documentation and/or
569   other materials provided with the distribution. Neither the name of the
570   author nor the names of its contributors may be used to endorse or
571   promote products derived from this software without specific prior
572   written permission.
573 
574 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
575 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
576 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
577 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
578 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
579 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
580 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
581 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
582 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
583 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
584 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Note: See TracBrowser for help on using the repository browser.