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.
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: