Contents (package MULK.OBJECTIVE-CL)


Macro DEFINE-OBJECTIVE-C-CLASS

Purpose:

Define a new Objective-C class.

Syntax:

define-objective-c-class name (&rest superclasses) (&rest slots) &body options

Arguments and Values:

name --- a symbol.

superclasses --- a list of symbols (not evaluated).

slots --- a list (not evaluated).

options --- a list (not evaluated).

Returns: class --- the class just defined.

Description:

define-objective-c-class is like defclass except in the following aspects:

  1. name is immediately replaced by a symbol interned in package objective-c-classes (that is, the ns namespace).

  2. If superclasses is the empty list, a default value of ns::ns-object will be used.

  3. If the class does not exist yet, the default value for the :metaclass option is ns::+ns-object. Otherwise, the default value is the name of the current metaclass of the class. (Note that supplying a value different from ns::+ns-object as the metaclass is usually not desirable. See the note below for details.)

  4. If any of the given superclasses in the ns namespace is unknown at load-time, it will be assumed to name an objective-c-class and registered prior to execution of the define-objective-c-class form.

  5. Slot specifications can specify foreign slots. See below for details.

If superclasses contains more than one symbol that names an objective-c-class (or that is assumed to as per (4) above), an error will be signalled.

If superclasses is not the empty list but does not contain a symbol that names an objective-c-class (or that is assumed to as per (4) above), the behaviour is undefined.

Foreign Slot Specifier Syntax:

slot ::= (slot-name [[slot-option | foreign-slot-option]]*)

foreign-slot-option ::= {:foreign-type typespec}} | {:foreign-name foreign-name}}

typespec --- a list or a symbol.

foreign-name --- a string.

Foreign Slot Specifier Description:

Foreign slot specifiers are like the standard slot specifiers that defclass recognises except that they also recognise the additional options :foreign-type and :foreign-name.

typespec is used to determine the C type the foreign slot will have.

If typespec is a symbol, it must be a CFFI type specifier, except that the values :id and :class are also recognised. If it is a list, it has to be a valid Objective-CL type specifier, whose syntax is not yet documented nor even finalised.

foreign-name is the name the slot will have on the Objective-C side. It must be a valid Objective-C ivar identifier.

If foreign-name is omitted, it is derived from slot-name by transforming it to Lower Camel Case as follows:

  1. If the name is not in canonical case, it is left alone.

  2. Otherwise, the name is split into parts separated by hyphens.

  3. Each part except the first is capitalised and the results are concatenated onto the first part in order.

Examples:

(define-objective-c-class mlk-my-class ()  
    ((foos :initargs :foos)  
     (foo-count :foreign-type :int)))  ;foreign name will be "fooCount"  
  => #<NS:+MLK-MY-CLASS NS:MLK-MY-CLASS {82c05c0}>  
  
(defvar *x* (invoke (find-objc-class 'mlk-my-class) 'new))  
  => *X*  
  
(slot-boundp *x* 'foo-count)            => T  
(setf (slot-value *x* 'foo-count) 100)  => 100  
(slot-value *x* 'foo-count)             => 100  
  
(slot-boundp *x* 'foos)                        => NIL  
(setf (slot-value *x* 'foos) (list 'a 'b 'c))  => (A B C)  
(slot-value *x* 'foos)                         => (A B C)  
 

Note:

Regardless of the :metaclass option given, the way ns::+ns-object is implemented will ensure that every objective-c-class gets its very own metaclass as in Objective-C. The user is therefore strongly discouraged from messing with the :metaclass option.

Note 2:

It is not an error to define classes of type objective-c-class in packages other than objective-c-classes, but doing so will make some code behave in unexpected ways, so it is not recommended.

Note 3:

Foreign slots are always slot-boundp, as it is impossible to determine whether they have been set on the Objective-C side or not. Because of this, one has to be very careful when using :string as the foreign-type.

See also:

defclass, define-objective-c-generic-function, define-objective-c-method