Skip to content

Latest commit

 

History

History
307 lines (191 loc) · 10.9 KB

objc.wiki

File metadata and controls

307 lines (191 loc) · 10.9 KB

toc: tags: eggs

== objc

=== Requirements

make matchable miscmacros fmt concurrent-native-callbacks

This extension makes use of dyncall, a library for constructing C function-calls at runtime. The library needs to be installed for this egg to function properly.

=== Introduction

This egg provides a leightweight interface to Objective-C. It has been tested on Linux with GNUstep and Mac OS X.

This egg is part of the chicken-mobile project. The sources are available here: https://github.com/chicken-mobile/concurrent-native-callbacks

=== Programming interface

==== Declarations and definitions

<syntax>(objc-import IMPORT ...)</syntax>

Expands into an preprocessor directive, the string designates an Objective-C headerfile and can alternatively be of the form .

This form is only available in compiled code.

<syntax>(define-objc-class NAME)</syntax>

Forward-declares an Objective-C class by expanding into a declaration.

This form can only be used in compiled code.

<syntax>(define-objc-interface NAME [:] DECLARATION ...)</syntax>

Defines an interface (as in ). and the optional should be symbols and valid Objective-C classnames.

A consists of field or method specifications:

Declaring a "field" (an instance variable):

Declaring a class or instance method (unary):


Declaring a class or instance method with arguments:

may be omitted and defaults to .

and follow normal foreign-type syntax. In addition to the usual foreign type specifiers, the types , and are also available and correspond to .

Note that this declaration is only valid inside the current compilation unit.

This form may only be used in compiled code.

<syntax>(define-objc-implementation NAME DEFINITION ...)</syntax>

Defines an implementation section for methods of the class (as in ).

should be of the form

where follows the syntax given above for . Additionally, asynchronously callable methods can be defined (see below).

Inside the expressions the implicit variable refers to the current receiver.

This form can only be used in compiled code.

==== Method invocation

<syntax>(send RECEIVER SELECTOR ARGUMENT ...)</syntax>

Sends the message given in the symbol or keyword to the object with the given arguments and returns its result.

<syntax>(send/block RECEIVER SELECTOR ARGUMENT ...)</syntax>

Returns a C block pointer, that, when invoked will send the message with the arguments given. Note that the receiver and the arguments are evaluated when the block is created. The returned block is heap-allocated. Use to release the memory.

This syntax is only available on Mac OS X / iOS.

<syntax>(send/main-thread RECEIVER SELECTOR ARGUMENT ...)</syntax>

Creates a C block wrapping the method-invocation and adds it to the dispatch queue of the main thread.

This syntax is only available on Mac OS X / iOS.

<syntax>(@selector NAME)</syntax>

Returns the selector with the given name, which should be a symbol or keyword. The is not evaluated.

<syntax>(@ RECEIVER SELECTOR ARGUMENT ...)</syntax> <syntax>(@/block RECEIVER SELECTOR ARGUMENT ...)</syntax> <syntax>(@/main-thread RECEIVER SELECTOR ARGUMENT ...)</syntax>

A slightly more convenient syntax for sending messages:

  • is equivalent to .
  • is equivalent to . The receiver may be the special variable which sends to a message to but starts the message-lookup in the superclass of the receiver (this is only valid inside a method-implementation).
and have the obvious meaning and are only available on Mac OS X / iOS.

==== Objects

<procedure>(object? X)</procedure>

Returns true if is an object- or class-pointer or otherwise.

<procedure>(object-ref OBJECT SYMBOL)</procedure>

Returns the instance-variable named of the given instance.

<procedure>(object-set! OBJECT SYMBOL X)</procedure>

Assigns to the instance-variable of the given instance. Alternatively you can also use the form .

<variable>nil</variable>

The same as which is CHICKEN's representation of a NULL pointer.

==== Classes

<class>Object</class>

Holds a pointer to class .

<procedure>(class? X)</procedure>

Returns true if is a class-pointer or otherwise.

<procedure>(metaclass? X)</procedure>

Returns true if is a pointer to a meta-class or otherwise.

<procedure>(class-of OBJECT)</procedure>

Returns a pointer to the class of the given object. If is a class, the result will be a metaclass instance.

<procedure>(class-name CLASS)</procedure>

Returns the name of the given class, which is a string.

<procedure>(find-class NAME)</procedure>

Finds the class with the given name (which should be string) or if no such class exists.

<procedure>(superclass-of CLASS)</procedure>

Returns the superclass of the given class or if is a root class.

==== Selectors

<procedure>(selector? X)</procedure>

Returns true if is a selector-pointer or otherwise.

<procedure>(string->selector STRING)</procedure>

Returns a pointer to the selector object for the selector with the name .

<procedure>(selector->string SELECTOR)</procedure>

Returns the name of the given selector-pointer.

==== Asynchronously callable methods

Methods defined with or inside a declaration may (and must) be called from a native thread other than the thread in which the CHICKEN runtime system executes:

<enscript highlight="scheme"> (define-objc-implementation Foo ((-/async ping: (int)x) (print "ping: " x) self)) &lt;/scheme&gt;</enscript>

The implementation of asychronously callable methods uses the concurrent-native-callbacks internally.

Note: calling such a method from the same thread will block indefinitely. ==== Blocks

<procedure>(block-copy BLOCK)</procedure>

Allocates and copies the block referenced to by the block-pointer , which is either the result of claling or . The copied block is returned.

On platforms other than Mac OS X / iOS, this procedure does nothing and returns .

<procedure>(block-release! BLOCK)</procedure>

Releases the memory occupied by the previously copied block .

On platforms other than Mac OS X / iOS, this procedure does nothing.

==== Method-call read-syntax

<syntax>[RECEIVER]</syntax>

A convenience read-syntax to make method-invocations look more natural. It is entirely equivalent to . To use this syntax, pass

  -X objc-read-syntax

to the compiler when compiling Scheme code using this syntax, or use

  (use objc-read-syntax)

in interpreted code. Note that is often used as an alternative to , which is the default behaviour in the CHICKEN reader.

=== Restrictions

A number of restrictions and limitations exist:

  • Class-declaration and -definition is only possible in compiled code.
  • Instances, classes and selectors are generally passed around as "tagged pointers" which is relatively lightweight but shows little information about the object when printed.
  • All method calls are implicitly "safe", they allow callbacks (as in . This is slower than using unsafe calls. Currently there is no unsafe method-invocation variant.
  • Instance-variables can be assigned strings or vectors or any structured data in general, if the data belongs to Scheme.
  • Method-call performance is not particularly good.
=== Issues

On newer Linux systems, dynamic loading of shared objects that are marked as having an executable stack area will result in a runtime-error. This applies mostly to code that has been built from assembler sources and is in fact the case in the dyncall library. This issue will be fixed in the next release of but in the time being you can apply the following patch tot he sources:

=== Version History

0.1 : initial release
=== License

  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
  conditions are met:
  
    Redistributions of source code must retain the above copyright notice, this list of conditions and the following
      disclaimer.
    Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided with the distribution.
    Neither the name of the author nor the names of its contributors may be used to endorse or promote
      products derived from this software without specific prior written permission.
  
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE.