Hi all,
Objective-CL 0.2.0 has been released. This release is a major
milestone on the way to 1.0.0.
* Quick summary
We can now define Objective-C classes and methods without writing a
single line of Objective-C code. The API may not be stable and there
might be crashes, but living dangerously is half the fun, right? ;)
* What's new?
** Method call syntax
#.(enable-method-syntax)
We now support Clozure CL's new method call syntax via reader macros.
That means you can write:
(let ((lock (#/new (find-objc-class 'ns-lock))))
(#/lock lock)
(print (#/stringWithCString:encoding: (find-objc-class 'ns-string)
"Hi there!" 0))
(#/unlock lock))
In fact, as the reader macro does no more than offer an alternate
syntax for symbols, you can do things like using it with APPLY as
well:
(apply #'#/stringWithUTF8String: (find-objc-class 'ns-string) (list
"Hi again."))
** Class definition
You can now define classes. For example, the following will define a
subclass of NSObject called MLKMyClass, including a native slot called
FOOS and a foreign slot (that is, an Objective-C ivar) called
FOO-COUNT (fooCount on the Objective-C side):
(define-objective-c-class ns::mlk-my-class (ns::ns-object)
((foos :initargs :foos)
(foo-count :foreign-type :int)))
Simple CFFI type specifiers are recognised by :FOREIGN-TYPE, but
please note that complex types such as struct and union types are not
yet supported.
** Method definition
You can now define Objective-C methods from Lisp for your own classes.
The following will define the Objective-C method
-(int)foo:(int)bar:(id)stuff:(id)do:(NSNumber *) on MLKMyClass
instances:
(define-objective-c-generic-function #/foo:bar:stuff:do: (self y z a b))
(define-objective-c-method #/foo:bar:stuff:do: :int
((self ns::mlk-my-class) (y :int) z a (b ns::ns-number))
(format t "Hello! Z and A are ~A and~&~A, respectively. Have a
nice day." z a)
(+ y 20))
Usage example:
OBJECTIVE-CL> (invoke (invoke (find-objc-class 'mlk-my-class) 'new)
:foo 3 :bar "abc" :stuff 3 :do 33)
Hello! Z and A are #<NS:GSC-BUFFER-STRING `abc' {8230318}> and
#<NS:GS-CACHED-INT `3' {812C5D0}>, respectively. Have a nice day.
23
Note that, at present, you absolutely have to call
DEFINE-OBJECTIVE-C-GENERIC-FUNCTION before defining methods, because
otherwise you're going to get the wrong type of generic function.
All modifiers of the standard method combination should be supported
in principle, but it's unlikey they'll work as expected. This is
planned for a future release.
&REST and &KEY arguments are not supported.
#.(disable-method-syntax)
** Struct wrappers
When an Objective-C method returns a struct, it is now wrapped in a
FOREIGN-STRUCT; likewise for unions. If you want to prevent its
automatic deallocation, you need to set its
FOREIGN-VALUE-LISP-MANAGED-P property to false. This change has been
made because it would otherwise not be safe to discard return values
of Objective-C methods, a safety which both Objective-C and Lisp
programmers have come to expect.
** COLLECT-CLASSES
The new function COLLECT-CLASSES may be used to make all classes known
to the Objective-C runtime available as CLOS classes under the NS
namespace. In an ideal world, we'd do this automatically at system
load-time, but registering such a large number of classes along with
their metaclasses takes a long time on some CL implementations (CMUCL,
SBCL), so it's the user's decision whether to use FIND-OBJC-CLASS for
each class or COLLECT-CLASSES once for now.
If you try the release out, please tell me what works and what
doesn't. If you can't even get it to compile, that is helpful
information as well.
Of course, above all, have lots of fun!
~ Matthias