ObjCMethod objects

An ObjCMethod instance is returned when you ask to an ObjCObject a particular selector. By ``calling'' it, you execute the associated Objective-C method. It knows about the number of arguments the selector accepts, and their type, so that it's able to convert a Python value to a suitable C value, and viceversa. For example, when a selector takes a struct value, you actually feed it a Python tuple object, then the ObjCMethod will convert that tuple to the needed C struct value; if it returns a char * value, you actually receive a standard Python string object. The same translation happens for C arrays. Other types get translated as you'd expect, except for char values, that are converted to integers[*], although single-char strings are accepted as arguments. When a selector is expected, you can give it both as its concise string representation or by passing an ObjCMethod instance of it.

To explain better, given the Objective-C declarations:

typedef struct _point { float x,y } Point;
typedef struct _size { float w,h } Size;
typedef struct _rect { Point origin; Size size } Rect;

@interface Square : Object
{
  Rect frame;
}

- initWithFrame:(Rect) r;
- (void) getFrame:(Rect *) r;
- (void) perform:(SEL) sel;
- (void) show;

@end

to pass the r argument to initWithFrame: you must build a tuple of two items, the first to be a tuple with two elements for the origin, with values for x and y in it; the second for the size slot, another tuple containing values for w and h. This gives:

>>> import ObjC
>>> myroom = ObjC.runtime.Square.alloc()
>>> myroom.initWithFrame__ ( (0.0, 0.0), (12.3, 8.1) )
>>> ...
>>> # these are equivalent
>>> myroom.perform__ ("show")
>>> myroom.perform__ (myroom.show)

A little complication arises with methods that take a pass-by-reference argument: usually such arguments are used when the selector wants to return more than one value, for example a status of operation and an actual result value. In this case the method may modify its arguments; since in Python there is no notion of pass-by-reference argument syntax, you must use a different way.


\begin{funcdesc}{pack_argument}{argn\optional{, value}}
This method builds a \df...
...t given, the content of the packed
value will not be initialized.
\end{funcdesc}


\begin{funcdesc}{unpack_argument}{argn, packedValue}
This method takes the packe...
...ct, or from a
\code{.pack\_argument()}, ie an ObjCPointer object.
\end{funcdesc}

Given the Objective-C declaration above, to get the frame of a Square object you should use

>>> ...
>>> framep = myroom.getFrame__.pack_argument (0)
>>> myroom.getFrame__ (framep)
>>> itsFrame = myroom.getFrame__.unpack_argument (0, framep)
>>> # which by the way is the same as
>>> itsFrame = framep.unpack()

Note that ObjCMethod will silently slurp the argument if passed in the normal way, ie not in packed form, but you won't be able to fetch its modified value, that is

>>> ...
>>> frame = ( (0.0, 0.0), (0.0, 0.0) )
>>> myroom.getFrame__ (frame)
>>> print frame
>>> ((0.0,0.0),(0.0,0.0))

An ObjCMethod has these data members:


\begin{datadesc}{name}
This is the name of the ObjC selector this object is wrapping.
\end{datadesc}


\begin{datadesc}{__members__}
The list of data members of this object.
\end{datadesc}