- (define-objc-class CLASS SUPERCLASS IVARS . METHODS)syntax
Defines CLASS (a symbol) with superclass SUPERCLASS (a symbol), instance variables IVARS, and methods METHODS. The new classname is imported with define-objc-classes.
SUPERCLASS is looked up for you in the runtime, so it need not be imported.
IVARS is a list of the form ((TYPE NAME) ...), where TYPE is a type qualifier and NAME is a symbol representing the new variable name. Each instance of CLASS will have a separate copy of these variables.
METHODS 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.
You can also use + as an alias for define-class-method and - for define-method. These correspond to Objective C method definition syntax.
Example: (define-objc-class MyPoint NSObject ((DBL x) (DBL y) (slot: closure)) (define-method ID init (print "MyPoint init") (@ super init)) (- DBL getX @x) (- DBL getY @y) (- ID description (sprintf "<MyPoint: (~a, ~a)>" @x @y)) (- VOID ((move-by-x: DBL a) (y: DBL b)) (set! @x (+ a @x)) (ivar-set! self y (+ b (ivar-ref self y)))) ;; more wordy (- ID ((init-with-x: DBL a) (y: DBL b)) (let ((p (@ self init))) (@ p move-by-x: a y: b) (set! @closure (lambda (msg) (cond ((eq? msg 'initial-x) (print "MyPoint: initial x was " a)) ((eq? msg 'initial-y) (print "MyPoint: initial y was " b))))) p))) #;1> (define p (@ (@ MyPoint alloc) init-with-x: 3.4 y: 4.5)) MyPoint init #;2> (@ p move-by-x: 2 y: 3) #<objc-instance <MyPoint: (5.4, 7.5)>> #;3> ((ivar-ref p closure) 'initial-x) MyPoint: initial x was 3.4