Contents (package MULK.OBJECTIVE-CL)


Function INVOKE

Purpose:

Send a message to an Objective-C instance.

Syntax:

invoke receiver message-start &rest message-components

Arguments and Values:

receiver --- an Objective-C wrapper object.

message-start --- a symbol.

message-components --- an alternating list of objects and symbols.

Returns: result --- the return value of the method invocation.

Description:

All even-numbered message components are collected in order and the resulting list used as if as additional arguments to invoke-by-name.

All uneven-numbered message components, which must be symbols, are first split into parts separated by hyphens and each part converted into a string according to the following rules:

    1. If the keywords' symbol names do contain lowercase characters, their case is left intact.
    2. If the keywords' symbol names do not contain any lowercase characters, the following steps are taken in order to adjust their case.

      1. The first part is fully converted to lowercase.
      2. Any additional parts are also fully converted to lowercase except for their first letters, which are left intact.
  1. If the symbol is a keyword, the resulting string is suffixed by a colon (`:').

After that, all parts are concatenated in order to form a single message name component. The message name components are in turn concatenated in order to form the message name which is used as if as the second argument to invoke-by-name.

Examples:

(invoke (find-objc-class 'ns-string)  
        :string-with-u-t-f-8-string "Mulk.")  
  ;=> #<GSCBufferString `Mulk.' {5B36087}>  
  
(invoke (find-objc-class 'ns-string)  
        '|:stringWithUTF8String| "Mulk.")  
  ;=> #<GSCBufferString `Mulk.' {5B36087}>  
  
(invoke (find-objc-class 'ns-object)  
        'self)                            
  ;=> #<NSObject `NSObject' {16ECF598}>  
  
(invoke (find-objc-class 'ns-object)  
        'name)                            
  ;=> "NSObject"  
  
(invoke (find-objc-class 'ns-string)  
        :string-with-c-string "Mulk."  
        :encoding 4)  
  ;=> #<GSCBufferString `Mulk.' {5B36087}>  
  
#.(setq *readtable* (copy-readtable))  
#.(setf (readtable-case *readtable*) :invert)  
(invoke (find-objc-class 'ns-string)  
        :stringWithCString "Mulk."  
        :encoding 4)  
  ;=> #<GSCBufferString `Mulk.' {5B36087}>  
 

Note:

Setting the readtable case of the current readtable to :INVERT is a good way of making the Lisp system behave as traditionally as possible while making Objective-C method names case-sensitive.

On the other hand, writing all method names in lower case while separating parts by hyphens works nicely in all of the :INVERT, :UPCASE, :DOWNCASE, and :PRESERVE modes as well as Allegro CL's modern mode.

Note 2:

Instead of using invoke, which is neither macro-friendly nor very useful for method selection at run-time, you may funcall selectors directly. Naturally, apply works as well.

The following calls are all equivalent (though the last one needs the syntax enhancement provided by enable-method-syntax enabled and the selector registered by way of collect-methods):

(invoke-by-name class "stringWithCString:encoding:" "Mulk." 4)  
(invoke class :string-with-c-string "Mulk." :encoding 4)  
(funcall (selector "stringWithCString:encoding:") class "Mulk." 4)  
(apply (selector "stringWithCString:encoding:") (list class "Mulk." 4))  
(#/stringWithCString:encoding: class "Mulk." 4) 

See also:

invoke-by-name