objc – The PyObjC bridge

Introduction

The module objc is the core of PyObjC and provides the automatic bridging between Python and Objective-C. It also provides a number of utility functions and types that make it easier to integrate Python and Objective-C code.

The module objc defines a number of functions whose names start with an underscore. Those functions are private and should not be used, they can be removed from release without warning.

NOTE: This document is currently mostly an exhaustive list of stuff and needs to be reorganised once I’ve filled in the technical details.

Bridge options

objc.options

The object options has attributes for reading and setting a number of configuration options for the bridge.

Attributes whose names start with an underscore are reserved for use by the bridge and can appear or disappear with every release of PyObjC.

New in version 3.0.

objc.options.verbose

When the value is True the bridge will log more information.

This currently results in output on the standard error stream whenever an exception is translated from Python to Objective-C.

objc.options.use_kvo

The default value for the __useKVO__ attribute on classes.

When the __useKVO__ attribute of a class is true instances of the class will generate Key-Value Observation notifications when setting attributes from Python.

objc.options.unknown_pointer_raises

When True (the default) the bridge will raise an exception when it encounters a pointer value that cannot be converted to Python, otherwise it it creates instances of ObjCPointer.

objc.options.strbridge_enabled

Python 2 only: When True (the default) instances of str are bridged as instances of a subclass of NSString, otherwise strings are not bridged.

Note

This option is only relevant for Python 2.x, for Python 3.x instances of str are bridged as instances of a subclass of NSString and instances of bytes ( the str class in Python 2) are bridged as instances of a subclass of NSData.

Deprecated functions for changing options

objc.setVerbose(yesOrNo)

When the argument is True the bridge will log more information.

This currently results in output on the standard error stream whenever an exception is translated from Python to Objective-C.

Deprecated since version 3.0: Use objc.options instead

objc.getVerbose()

Returns the current value of the verbose flag.

Deprecated since version 3.0: Use objc.options instead

objc.setUseKVOForSetattr()

Sets the default value for the __useKVO__ attribute on classes defined after this call. Returns the previous value.

When the __useKVO__ attribute of a class is true instances of the class will generate Key-Value Observation notifications when setting attributes from Python.

Deprecated since version 3.0: Use objc.options instead

objc.setStrBridgeEnabled(yesOrNo)

If yesOrNo is true instances of str are bridged as NSString instances, otherwise bridging issues a PyObjCStrBridgeWarning warning and still bridges as an NSString instances.

By default PyObjC behaves as if setStrBridgeEnabled(True) was called.

Note

This function is not available in Python 3.x

Note

Setting this option to false is discouraged and is mostly usefull when porting to Python 3.

Deprecated since version 3.0: Use objc.options instead

objc.getStrBridgeEnabled()

Returns True if the str bridge is enabled and False when it is not.

Note

This function is not available in Python 3.x

Deprecated since version 3.0: Use objc.options instead

Weak references

class objc.WeakRef(object)

It is not possible to use the weakref module to create weak references to Cocoa objects due to implementation restrictions (at best it would be possible to create a weakref to the Python proxy for such objects).

PyObjC implements a zero-ing weakref object when running on Mac OS X 10.7 or later. These objects more or less behave the same as __weak variables in Objective-C.

The object must be a Cocoa object, and must not be a CoreFoundation object (unless the CoreFoundation type is transparently bridged to Cocoa).

__call__()
Returns the weakly references object when that is still alive, otherwise returns None.

Note

Unlike weakref.ref this class cannot be subclasses, and does not have a callback option. The callback option cannot be reliably be implemented with the current Objective-C runtime API.

Warning

Some Cocoa classes do not support weak references, see Apple’s documentation for more information. Creating a weak reference to instances of such classes can be a hard error (that is, the interpreter crashes, you won’t get a nice exception).

Associated Objects

On Mac OS X 10.6 or later the Objective-C runtime has an API for associated objects, which are more or less additional instance variables for objects.

objc.setAssociatedObject(object, key, value, policy)
Parameters:
  • object – the base object (a Cocoa instance)
  • value – value for the associated object
  • policy – policy for the assiocation (see below)

Associate assoc with object under name name.

objc.getAssociatedObject(object, key)
Parameters:
  • object – an object (a Cocoa instance)
  • key – the key object that was used with setAssociatedObject()
Returns:

the value for the key, or None.

Returns the value of an associated object.

objc.removeAssociatedObjects(object)
Parameters:object – an object (a Cocoa instance)

Remove all associations for object. It is generally a bad idea to use this function, because other libraries might have set assocations as well.

objc.OBJC_ASSOCIATION_ASSIGN

Policy for creating a weak reference to the associated object

Note

Don’t use this when the value is a pure python object, unless you arrange to keep the proxy object alive some other way.

objc.OBJC_ASSOCIATION_RETAIN_NONATOMIC

Policy for creating a strong reference to the associated object.

objc.OBJC_ASSOCIATION_COPY_NONATOMIC

Policy for creating a strong reference to a copy of the assocated object.

objc.OBJC_ASSOCIATION_RETAIN

Policy for creating a strong reference to the associated object, the assocation is made atomically.

objc.OBJC_ASSOCIATION_COPY

Policy for creating a strong reference to a copy of the assocated object, the assocation is made atomically.

Utilities

objc.allocateBuffer(size)

Returns a writable buffer object of size bytes.

objc.CFToObject()

Converts an object from the standard library CF module to a PyObjC wrapper for the same CoreFoundation object. Raises an exception when the conversion fails.

Deprecated since version 2.4: part of support for the CF module in the python 2 std. library, will be removed in PyObjC 3.0.

Note

this function is not available for Python 3.

objc.ObjectToCF()

Converts a PyObjC wrapper for a CoreFoundation object to an object from the standard library CF module for the same CoreFoundation object. Raises an exception when the conversion fails.

Deprecated since version 2.4: part of support for the CF module in the python 2 std. library, will be removed in PyObjC 3.0.

Note

this function is not available for Python 3.

Accessing classes and protocols

objc.lookUpClass(classname)
Parameters:classname (string) – the name of an Objective-C class
Returns:the named Objective-C class
Raise:objc.nosuchclass_error when the class does not exist
objc.getClassList()
Returns:a list of a classes known to the Objective-C runtime
objc.protocolsForClass(cls)

Returns a list of Protocol objects that the class claims to implement directly. The cls object must a subclass of NSObject.

objc.protocolsForProcess()

Returns a list of all Protocol objects known to the Objective-C runtime.

objc.propertiesForClass(objcClass)
Returns:a list of properties from the Objective-C runtime

The return value is a list with information about properties on this class or protocol from the Objective-C runtime. This does not include properties superclasses.

Every entry in the list is dictionary with the following keys:

Key Description
name Name of the property (a string)
raw_attr Raw value of the attribute string (a byte string)
typestr The type string for this attribute (a byte string)
classname When the type string is objc._C_ID this is the name of the Objective-C class (a string).
readonly True iff the property is read-only (bool)
copy True iff the property is copying the value (bool)
retain True iff the property is retaining the value (bool)
nonatomic True iff the property is not atomic (bool)
dynamic True iff the property is dynamic (bool)
weak True iff the property is weak (bool)
collectable True iff the property is collectable (bool)
getter Non-standard selector for the getter method (a byte string)
setter Non-standard selector for the setter method (a byte string)

All values but name and raw_attr are optional. The other attributes contain a decoded version of the raw_attr value. The boolean attributes should be interpreted as False when the aren’t present.

The documentation for the Objective-C runtime contains more information about property definitions.

This function only returns information about properties as they are defined in the Objective-C runtime, that is using @property definitions in an Objective-C interface. Not all properties as they are commonly used in Objective-C are defined using that syntax, especially properties in classes that were introduced before MacOSX 10.5.

This function always returns an empty list on MacOS X 10.4.

New in version 2.3.

objc.listInstanceVariables(classOrInstance)

Returns a list of information about all instance variables for a class or instance. ClassOrInstance must be a subclass of NSObject, or an instance of such a class.

The elements of the list are tuples with two elements: a string with the name of the instance variable and a byte string with the type encoding of the instance variable.

objc.getInstanceVariable(object, name)

Returns the value of the instance variable name.

Warning

Direct access of instance variables should only be used as a debugging tool and could negatively affect the invariants that a class tries to maintain.

objc.setInstanceVariable(object, name, value[, updateRefCounts])

Set the value of instance variable name to value. When the instance variable type encoding is objc._C_ID updateRefCounts must be specified and tells whether or not the retainCount of the old and new values are updated.

Warning

Direct access of instance variables should only be used as a debugging tool and could negatively affect the invariants that a class tries to maintain.

Warning

It is very easy to introduce memory corruption when updateRefCounts is false. In particular the caller of this method must ensure that the Objective-C representation of value is kept alive, when value is not a Cocoa object just keeping value alive isn’t good enough.

objc.protocolNamed(name)

Returns a Protocol object for the named protocol. Raises ProtocolError when the protocol does not exist.

This is the equivalent of @protocol(name) in Objective-C.

exception objc.ProtocolError

Raised by protocolNamed() when looking up a protocol that does not exist.

Dynamic modification of classes

objc.classAddMethods(cls, methods)

Add a sequence of methods to the given class.

The effect is simular to how categories work in Objective-C. If the class already implements a method that is defined in methods the existing implementation is replaced by the new one.

The objects in methods should be one of:

  • selector instances with a callable (that is, the first argument to selector must not be None).
  • classmethod or staticmethod instances that wrap a function object.
  • functions
  • unbound methods

For the last two the method selector is calculated using the regular algoritm for this (e.g. as if selector(item) was called). The last two are instance methods by default, but automaticly made class methods when the class (or a superclass) has a class method with the same selector.

objc.classAddMethod(cls, name, method)

Adds function method as selector name to the given class. When method is a selector the signature and class-method-ness are copied from the selector.

Note

Adding a selector that’s defined in Objective-C to another class will raise an exception.

class objc.Category

A helper class for adding a category to an existing Objecive-C class (subclass of NSObject).

Usage:

class NSObject (Category(NSObject)):
   def method(self):
       pass

The metaclass uses classAddMethods() to add the methods in the category body to the base class.

The name of the class must be the same as the argument to Category.

Plugin bundles

objc.currentBundle()

During module initialization this function returns an NSBundle object for the current bundle. This works for application as well as plug-ins created using py2app.

After module initialization use NSBundle.bundleForClass_(ClassInYourBundle) to get the bundle.

Memory management

PyObjC automaticly manages Cocoa reference counts for you, the functions in this section help in finetuning this behaviour.

objc.recycleAutoreleasePool()

Flush the NSAutoreleasePool that PyObjC creates on import. Use this before entering the application main loop when you do a lot of work before starting the main loop.

objc.removeAutoreleasePool()

Use this in plugin bundles to remove the release pool that PyObjC creates on import. In plugins this pool will interact in unwanted ways with the embedding application.

objc.autorelease_pool()

A context manager that runs the body of the block with a fresh autorelease pool. The actual release pool is not accessible.

Usage:

with autorelease_pool():
    pass

Test support

The functions in this section are present as support code for PyObjC’s unittests and are not part of the stable API. Please let us know if you use these functions in your code.

objc.splitSignature(typestring)

Split an encoded Objective-C signature string into the encoding strings for seperate types.

Parameters:typestring (byte string) – an encoded method signature (byte string)
Returns:list of type signatures
Return type:list of byte strings
objc.splitStructSignature(typestring)

Returns (structname, fields). Structname is a string or None and fields is a list of (name, typestr) values. The name is a string or None and the typestr is a byte string.

Raises ValueError when the type is not the type string for a struct type.

objc.repythonify(object[, type])

Internal API for converting an object to a given Objetive-C type and converting it back again.

Framework wrappers

objc.pyobjc_id(obj)

Returns the address of the underlying object as an integer.

Note

This is basicly the same as id(), but for the Objective-C object wrapped by PyObjC instead of python objects.

Types

class objc.objc_class

This class is the metatype for Objective-C classes and provides no user-visible behavior.

class objc.objc_object([cobject[, c_void_p]])

This class is the root class for Objective-C classes, that is all wrappers for Objective-C classes are a subclass of this class. It is not possible to instantiate instances of Objective-C classes by using the class as a callable, instances are created using the standard Objective-C mechanisms instead.

The cobject and c_void_p arguments should always be passed as keyword arguments, and at most one of them should be provided. This will construct a proxy object of the right subclass of objc_object for the Cocoa object that the passed in value refers to. Cobject should be a Pytho capsule created using the __cobject__() method, c_void_p should be a ctypes.c_void_p.

Note

The normal way to create instances of (subclasses of) objc_object is to call the normal Cocoa allocation method. Calling the class should only be used to contruct a proxy from a pre-existing pointer value (for interoperability with other libraries).

pyobjc_ISA

Read-only property that returns the current Objective-C classes of an object.

pyobjc_instanceMethods

Read-only property that provides explicit access to just the instance methods of an object.

__block_signature__

Property with the type signature for calling a block, or None.

__cobject__()

Returns a capsule object with identifier “objc.__object__” and the a reference to the Objective-C object as the value.

__c_void_p__()

Returns a ctypes.c_void_p instance for this object.

__reduce__()

This method ensures that Objective-C objects will not be pickled unless the subclass explictly implements the pickle protocol. This is needed because the pickle will write an incomplete serialization of Objective-C objects for protocol 2 or later.

Note

The wrapper classes for the NSString class cluster aren’t subclasses of objc_object, but are subclasses of the builtin unicode type (str: in Python 3).

class objc.pyobjc_unicode

This class is used to wrap instances of the NSString class cluster and is a subclass of the builtin Unicode type (unicode for python 2 and str for Python 3).

Methods of the underlying NSString class can be accessed at as methods of the python type, unless they have the same name as a method of the built-in Unicode type.

nsstring()

Returns an instance of a subclass of objc_object that represents the string. This provides full access to the Cocoa string API, but without easy interoperability with Python APIs.

Note

Instances of NSString can be mutable. Mutations to mutable Cocoa strings are not reflected in instances of pyobjc_unicode, use nsstring() and explict conversion to the built-in unicode type when you work with mutable NSString values.

Note

Cocoa strings are wrapped using a subclass of the built-in unicode string to get better interaction between Python and Cocoa. Because Cocoa strings are instances of the built-in unicode type they can be passed to functions in extension modules that expect unicode arguments (in particular the file system access APIs such as open()).

class objc.selector(function[, selector[, signature[, isClassMethod[, returnType[, argumentTypes[, isRequired]]]]]])

This type is used to represent an Objective-C method.

Parameters:
  • function – The Python callable that is used for the method. Can be a classmethod , but not a staticmethod.
  • selector – The Objective-C selector for the method. The default is calculated from the __name__ attribute for function
  • signature – The type encoding for the method, the default signature assumes that all arguments and the result are objects (or ‘void’ when the function does not contain a return statement with a value).
  • isClassMethod – Used to specify if a method is a class method (default is True if function is a classmethod and False otherwise)
  • isRequired – Specify if the method is required (defaults to True), used in the definition of protocols.
callable

Read-only property with access to the underlying callable (the function argument to the constructor).

__doc__

Documentation string for the selector

__signature__

An inspect.Signature for the object

New in version 3.0.

Note

Only available for Python 3.3 or later.

__metadata__()

Returns a copy of the metadata dictionary for the selector. See the metadata system documentation for more information.

class objc.python_method(callable)

Use this as a decorator in a Cocoa class definition to avoid creating a selector object for a method.

This is used to add “normal” python methods to a class that’s inheriting from a Cocoa class and makes it possible to use normal Python idioms in the part of the class that does not have to interact with the Objective-C world.

For example:

class MyClass (NSObject):

   @python_method
   @classmethod
   def fromkeys(self, keys):
       pass

   @python_method
   def items(self):
       pass

In this example class MyClass has a Python classmethod “fromkeys” and a normal method “items”, neither of which are converted to a selector object and neither of which are registered with the Objective-C runtime.

Instances of this type have an attribute named callable containing the wrapped callable, but are themselves not callable.

New in version 3.0.

Note

If you use multiple decorators the python_method decorator should be the outermost decorator (that is, the first one in the list of decorators).

class objc.ivar([name[, type[, isOutlet]]])

Creates a descriptor for accessing an Objective-C instance variable. This should only be used in the definition of an Objective-C subclass, the bridge will use this information to create an instance variable with the same name on the Objective-C class itself.

Parameters:
  • name – Name of the instance variable. The name defaults to the name the instance variable is bound to in a class definition.
  • type – Type encoding for the instance varialble. Defaults to _C_ID (that is, an object)
  • isOutlet – If True the instance variable is used as an outlet, by default the instance variable is not an outlet.

Note

Sharing an ivar object between multiple class definitions is not supported.

Instances of ivar have a number of attributes that help with introspection:

  • __typestr__: The type encoding of the Objective-C type of the variable. See Objective-C type strings for more information.
  • __name__: The Objective-C name of the variable
  • __isOutlet__: True if the variable is an IBOutlet()
  • __isSlot__: True if the variable is a Python slot.

The ivar has convenience class methods for creating ivar objects for specific C types:

bool([name])

Create an instance variable that stores a value of C type bool. See the class description for a description of the name argument.

char([name])

Create an instance variable that stores a value of C type char. See the class description for a description of the name argument. In general it is better to use char_text() or char_int().

int([name])

Create an instance variable that stores a value of C type int. See the class description for a description of the name argument.

short([name])

Create an instance variable that stores a value of C type short. See the class description for a description of the name argument.

long([name])

Create an instance variable that stores a value of C type long. See the class description for a description of the name argument.

long_long([name])

Create an instance variable that stores a value of C type long long. See the class description for a description of the name argument.

unsigned_char([name])

Create an instance variable that stores a value of C type unsigned char. See the class description for a description of the name argument.

unsigned_int([name])

Create an instance variable that stores a value of C type unsigned int. See the class description for a description of the name argument.

unsigned_short([name])

Create an instance variable that stores a value of C type unsigned short. See the class description for a description of the name argument.

unsigned_long([name])

Create an instance variable that stores a value of C type unsigned long. See the class description for a description of the name argument.

unsigned_long_long([name])

Create an instance variable that stores a value of C type unsigned long long. See the class description for a description of the name argument.

float([name])

Create an instance variable that stores a value of C type float. See the class description for a description of the name argument.

double([name])

Create an instance variable that stores a value of C type double. See the class description for a description of the name argument.

BOOL([name])

Create an instance variable that stores a value of C type BOOL. See the class description for a description of the name argument.

UniChar([name])

Create an instance variable that stores a value of C type UniChar. See the class description for a description of the name argument. Values are (unicode) strings of length 1.

char_text([name])

Create an instance variable that stores a value of C type char. See the class description for a description of the name argument. Values are byte-strings of length 1.

char_int([name])

Create an instance variable that stores a value of C type char. See the class description for a description of the name argument. Values are integers in the range of a signed char in C.

Framework bindings introduce new class methods for creating instance variables whose type is a particular C struct, as an example the Foundation bindings introduce a class method named NSRange with the same signature as the methods mentioned earlier.

Note

You cannot access these attributes through an Objective-C instance, you have to access them through the class object. That’s because ivar is a data descriptor.

See also

Function IBOutlet()
Definition of outlets.
class objc.informal_protocol(name, selector_list)

This class is used to specify which methods are part of an informal protocol in Objective-C. Informal protocols are a documentation construct in Objective-C and as such are not present in the Objective-C runtime (as opposed to formal protocols).

Informal protocols are used by the bridge to automaticly update method signatures when a class appears to implement an informal protocol. This makes it possible the define a large subset of Cocoa functionality without manually setting method signatures.

Parameters:
  • name – Name of the protocol
  • selector_list – A sequence of selector instances, all of which should have no callable.
__name__

Read-only property with the protocol name

selectors

Read-only property with the sequence of selectors for this protocol

class objc.formal_protocol(name, supers, selector_list)

This class is used to represent formal protocols in Python, and is comparabile with the “@protocol” construct in Objective-C.

Parameters:
  • name – The name of the protocol
  • supers – A list of protocols this protocol inherits from
  • selector_list – A sequence of selector instances, all of which should have no callable.

Note

Constructing new protocols is supported on a subset of Mac OS X platforms:

  • All 32-bit programs
  • 64-bit programs starting from Mac OS X 10.7, but only when PyObjC was build with the 10.7 SDK (or later)
__name__

Read-only property with the name of the protocol

name()

Returns the name of the protocol

conformsTo_(proto)

Returns True if this protocol conforms to protocol proto, returns False otherwise.

descriptionForInstanceMethod_(selector)

Returns a tuple with 2 byte strings: the selector name and the type signature for the selector.

Returns None when the selector is not part of the protocol.

descriptionForClassMethod_(selector)

Returns a tuple with 2 byte strings: the selector name and the type signature for the selector.

Returns None when the selector is not part of the protocol.

instanceMethods()

Returns a list of instance methods in this protocol.

classMethods()

Returns a list of instance methods in this protocol.

Note

The interface of this class gives the impression that a protocol instance is an Objective-C object. That was true in earlier versions of Mac OS X, but not in more recent versions.

class objc.varlist

A C array of unspecified length. Instances of this type cannot be created in Python code.

This type is used when the API does not specify the amount of items in an array in a way that is usable by the bridge.

Warning

Access through a varlist object can easily read or write beyond the end of the wrapped C array. Read the Apple documentation for APIs that return a varlist to determine how many elements you can safely access and whether or not the array is mutable.

The C array might also be freed by C code before the varlist instance is garbage collected. The Apple documentation for the API should mention how long the reference is safe to use.

__typestr__

The type encoding for elements of the array. See Objective-C type strings for more information.

as_tuple(count)

Returns a tuple containing the first count elements of the array.

__getitem__(index)

Returns the value of the index-th element of the array. Supports numeric indexes as well as slices with step 1. Negative indexes are not supported because these objects have an undefined length.

__setitem__(index, value)

Sets the value of the index-th element of the array. Supports numeric indexes as well as slices with step 1 (but assigning to a slice is only possible when that does not resize the array). Negative indexes are not supported because these objects have an undefined length.

Warning

When underlying data type is objc._C_ID (that is, an array of Cocoa objects it is very likely that the retain count of the object needs to be adjusted. The __setitem__() method stores a reference to the object without adjusting any reference counts.

The correct behavior depends on the kind of array used, when the array is documented as containing strong references you should increase the retain count of the new value and lower the retain of the old value (in that order).

class objc.function

Instances of this class represent global functions from Cocoa frameworks. These objects are created using loadBundleFunctions() and loadFunctionList().

__doc__

Read-only property with the documentation string for the function.

__name__

Read-only property with the name of the function

__module__

Read-write property with the module that defined the function

__signature__

An inspect.Signature for the object

New in version 3.0.

Note

Only available for Python 3.3 or later.

__metadata__()

Returns a copy of the metadata dictionary for the selector. See the metadata system documentation for more information.

class objc.IMP

This class is used to represent the actual implementation of an Objective-C method (basicly a C function). Instances behave the same as unbound methods: you can call them but need to specify the “self” argument.

isAlloc

Read-only attribute that specifies if the IMP is an allocator (that is, the implementation of “+alloc” or one of its variant)

isClassMethod

Read-only attribute that specified if the IMP is for a class method.

signature

Read-only attribute with the type encoding for the IMP.

selector

Read-only attribute with the selector for the method that this IMP is associated with.

__name__

Alias for selector.

__signature__

An inspect.Signature for the object

New in version 3.0.

Note

Only available for Python 3.3 or later.

__metadata__()

Returns a copy of the metadata dictionary for the selector. See the metadata system documentation for more information.

class objc.super

This is a subclass of super that works properly for Objective-C classes as well as regular Python classes.

The regular super does not work correctly for Cocoa classes, the default function doesn’t support custom attribute getters as used by PyObjC.

Constants

objc.nil

Alias for None, for easier translation of existing Objective-C code.

objc.YES

Alias for True, for easier translation of existing Objective-C code.

objc.NO

Alias for False, for easier translation of existing Objective-C code.

objc.NULL

Singleton that tells the bridge to pass a NULL pointer as an argument when the (Objective-)C type of that argument is a pointer.

This behavior of the bridge is slightly different from using None: with None the bridge will allocate some memory for output parameters and pass a pointer to that buffer, with NULL the bridge will always pass a NULL pointer.

objc.MAC_OS_X_VERSION_MAX_ALLOWED

The value of MAC_OS_X_VERSION_MAX_ALLOWED when PyObjC was compiled.

objc.MAC_OS_X_VERSION_MIN_REQUIRED

The value of MAC_OS_X_VERSION_MIN_REQUIRED when PyObjC was compiled.

objc.PyObjC_BUILD_RELEASE

The version number of the SDK used to build PyObjC, in the same format as MAC_OS_X_VERSION_10_N

objc.MAC_OS_X_VERSION_10_N

There are currently 6 constants of this form, for N from 1 to 10, and these have the same value as the Objective-C constant of the same name.

objc.platform

This always has the value “MACOSX”.

Objective-C type strings

The Objective-C runtime and the PyObjC bridge represent the types of instance variables and methods arguments and return values as a string with a compact representation. The Python representation of that string is a byte string (that is type bytes in Python 3.x and str in Python 2.x).

Basic types

The representation for basic types is a single character, the table below lists symbolic constants in the for those constants.

Name Objective-C type
_C_ID id (an Objective-C instance)
_C_CLASS an Objective-C class
_C_SEL a method selector
_C_CHR char
_C_UCHR unsigned char
_C_SHT short
_C_USHT unsigned short
_C_BOOL bool (or _Bool)
_C_INT int
_C_UINT unsigned int
_C_LNG long
_C_ULNG unsigned long
_C_LNG_LNG long long
_C_ULNG_LNG unsigned long long
_C_FLT float
_C_DBL double
_C_VOID void
_C_UNDEF “other” (such a function)
_C_CHARPTR C string (char*)
_C_NSBOOL BOOL
_C_UNICHAR UniChar
_C_CHAR_AS_TEXT char when uses as text or a byte array
_C_CHAR_AS_INT int8_t (or char when
used as a number)

The values _C_NSBOOL, _C_UNICHAR, _C_CHAR_AS_TEXT, and _C_CHAR_AS_INT are inventions of PyObjC and are not used in the Objective-C runtime.

Complex types

More complex types can be represented using longer type strings:

  • a pointer to some type is _C_PTR followed by the type string of the pointed-to type.

  • a bitfield in a structure is represented as _C_BFLD followed by an integer with the number of bits.

    Note that PyObjC cannot convert bitfields at this time.

  • a C structure is represented as _C_STRUCT_B followed by the struct name, followed by '=', followed by the encoded types of all fields followed by _C_STRUCT_E. The field name (including the closing equals sign) is optional.

    Structures are assumed to have the default field alignment, although it is possible to use a custom alignment when creating a custom type for a struct using objc.createStructType().

  • a C union is represented as _C_UNION_B followed by the struct name, followed by '=', followed by the encoded types of all fields followed by _C_UNION_E. The field name (including the closing equals sign) is optional.

    Note that PyObjC cannot convert C unions at this time.

  • a C array is represented as _C_ARY_B followed by an integer representing the number of items followed by the encoded element type, followed by _C_ARY_E.

  • The C construct ‘const’ is mapped to _C_CONST, that is a const char* is represented as _C_CONST + _C_CHARPTR.

Additional annotations for method and function arguments

Method arguments can have prefixes that closer describe their functionality. Those prefixes are inheritted from Distributed Objects are not used by the Objective-C runtime, but are used by PyObjC.

  • When a pointer argument is an input argument it is prefixed by _C_IN.
  • When a pointer argument is an output argument it is prefixed by _C_OUT.
  • When a pointer argument is an input and output argument it is prefixed by _C_INOUT.
  • Distributed objects uses the prefix _C_BYCOPY to tell that a value should be copied to the other side instead of sending a proxy reference. This is not used by PyObjC.
  • Distributed objects uses the prefix _C_ONEWAY on the method return type to tell that the method result is not used and the caller should not wait for a result from the other side. This is not used by PyObjC.

When a pointer argument to a function prefixed by _C_IN, _C_OUT or _C_INOUT the brige assumes that it is a pass by reference argument (that is, a pointer to a single value), unless other information is provided to the bridge.

The _C_IN, _C_INOUT and _C_OUT encodings correspond to the keyword in, inout and out in Objective-C code. This can be used to add the right information to the Objective-C runtime without using the metadata system. For example:

@interface OCSampleClass

-(void)copyResourceOfName:(NSString*)name error:(out NSError**)error;

@end

This tells the compiler that error is an output argument, which doesn’t affect code generation or compiler warnings but does result in _C_OUT being present in the type encoding for the argument.

Special encoded types

The table below shows constants for a number of C types that are used in Cocoa but are not basic C types.

Constant Objective-C type
_C_CFTYPEID CFTypeID
_C_NSInteger NSInteger
_C_NSUInteger NSUInteger
_C_CFIndex CFIndex
_C_CGFloat CGFloat
_sockaddr_type struct sockaddr

Context pointers

A number of Objective-C APIs have one argument that is a context pointer, which is a void*. In Objective-C your can pass a pointer to an arbitrary value, in Python this must be an integer.

PyObjC provides a context object that can be used to allocate unique integers and map those to objects.

context.register(value)

Add a value to the context registry.

Parameters:value – An arbitrary object
Returns:A unique integer that’s suitable to be used as a context pointer (the handle).
context.unregister(value):

Remove an object from the context registery, this object must be have been added to the registry before.

Parameters:value – An object in the context registry
context.get(handle)

Retrieve an object from the registry given the return value from context.register().

Descriptors

objc.IBOutlet([name])

Creates an instance variable that can be used as an outlet in Interface Builder. When the name is not specified the bridge will use the name from the class dictionary.

The code block below defines an instance variable named “button” and makes that available as an outlet in Interface Builder.

class SomeObject (NSObject):

    button = IBOutlet()

Note

The IBOutlet function is recognized by Interface Builder when it reads Python code.

objc.IBAction(function)

Mark an method as an action for use in Interface Builder. Raises TypeError when the argument is not a function.

Usage:

class SomeObject (NSObject):

   @IBAction
   def saveDocument_(self, sender):
       pass

Note

The IBOutlet decorator is recognized by Interface Builder when it reads Python code. Beyond that the decoerator has no effect.

objc.IBInspectable(prop)

Mark a property as a value that can be introspected in IB.

See the Xcode documentation <https://developer.apple.com/library/ios/recipes/xcode_help-IB_objects_media/chapters/CreatingaLiveViewofaCustomObject.html> for more information on this decorator.

objc.IB_DESIGNABLE(cls)

Class decorator to tell IB that the class can be used in IB designs.

See the Xcode documentation <https://developer.apple.com/library/ios/recipes/xcode_help-IB_objects_media/chapters/CreatingaLiveViewofaCustomObject.html> for more information on this decorator.

objc.instancemethod()

Explicitly mark a method as an instance method. Use this when PyObjC incorrectly deduced that a method should be a class method.

Usage:

class SomeObject (NSObject):

   @instancemethod
   def alloc(self):
       pass

Note

There is no function named objc.classmethod, use classmethod to explictly mark a function as a class method.

objc.accessor()

Use this decorator on the definition of accessor methods to ensure that it gets the right method signature in the Objective-C runtime.

The conventions for accessor names that can be used with Key-Value Coding is described in the Apple documentation for Key-Value Coding

The table below describes the convention for methods for a property named ‘<property>’, with a short description and notes. The Apple documentation for Key-Value Coding contains more information.

Name Description Notes
property Getter for a basic property.  
isProperty Likewise, for a boolean property. PyObjC won’t automaticly set the correct property type, use typeAccessor() instead of accessor().
setProperty_ Setter for a basic property  
countOfProperty Returns the number of items in a indexed property, or unordered property  
objectInPropertyAtIndex_ Returns the object at a specific index for an indexed property  
propertyAtIndexes_ Returns an array of object values at specific indexes for an indexed property. The argument is an NSIndexSet. Don’t use this with typedAccessor().
getProperty_range_ Optimized accessor Not supported by PyObjC, don’t use
insertObject_inPropertyAtIndex_ Add an object to an indexed property at a specific index.  
insertProperty_atIndexes_ Insert the values from a list of at specific indices. The arguments are an NSArray and an NSIndexSet. Don’t use this with typedAccessor().
removeObjectFromPropertyAtIndex_ Remove the value at a specific index of an indexed property.  
removePropertyAtIndexes_ Remove the values at specific indices of an indexed property. The argument is an NSIndexSet.  
replaceObjectInPropertyAtIndex_withObject_ Replace the value at a specific index of an indexed property.  
replacePropertyAtIndexes_withProperty_ Replace the values at specific indices of an indexed property. Don’t use with typedAccessor()
enumeratorOfProperty Returns an NSEnumerator for an unordered property.  
memberOfProperty_ Returns True if the value is a member of an unordered property  
addPropertyObject_ Insert a specific object in an unordered property.  
addProperty_ Add a set of new values to an unordered property.  
removePropertyObject_ Remove an object from an unordered property.  
removeProperty_ Remove a set of objects from an unordered property.  
intersectProperty_ Remove all objects from an unorderd property that are not in the set argument.  
validateProperty_error_ Validate the new value of a property For typed accessor’s the value is wrapped in an NSValue (but numbers and booleans are automaticly unwrapped by the bridge)

PyObjC provides another mechanism for defining properties: object_property.

Changed in version 2.5: Added support for unordered properties. Also fixed some issues for 64-bit builds.

objc.typedAccessor(valueType)

Use this decorator on the definition of accessor methods to ensure that it gets the right method signature in the Objective-C runtime.

The valueType is the encoded string for a single value.

Note

When you use a typed accessor you must also implement “setNilValueForKey_”, as described in the Apple documentation for Key-Value Coding

objc.typedSelector(signature)

Use this decorator to explicitly set the type signature for a method.

An example:

@typedSelector(b'I@:d')
def makeUnsignedIntegerOfDouble_(self, d):
   return d
objc.namedSelector(name[, signature])

Use this decorator to explictly set the Objective-C method name instead of deducing it from the Python name. You can optionally set the method signature as well.

objc.callbackFor(callable[, argIndex=])

Use this decorator to tell that this function is the callback for an (Objective-C) API that stores a reference to the callback function.

You only have to use this API when the Objective-C API can store the callback function for later usage. For other functions the bridge can create a temporary callback stub.

Using this decorator for methods is not supported

Usage:

@objc.callbackFor(NSArray.sortedArrayUsingFunction_context\_)
def compare(left, right, context):
    return 1

This tells the bridge that ‘compare’ is used as the sort function for NSArray, and ensures that the function will get the correct Objective-C signature.

Note

The example will also work without the decorator because NSArray won’t store a reference to the compare function that is used after ‘sortedArrayUsingFunction_context_’ returns.

objc.callbackPointer(closure)

Returns a value that can be passed to a function expecting a void * argument. The value for closure must be a function that’s decorated with callbackFor().

New in version 3.1.

objc.selectorFor(callable[, argIndex])

Decorator to tell that this is the “callback” selector for another API.

Usage:

@objc.selectorFor(NSApplication.beginSheet_modalForWindow_modalDelegate_didEndSelector_contextInfo_)
def sheetDidEnd_returnCode_contextInfo_(self, sheet, returnCode, info):
    pass

This will tell the bridge that this method is used as the end method for a sheet API, and will ensure that the method is registered with the correct Objective-C signature.

objc.synthesize(name[, copy[, readwrite[, type[, ivarName]]]])
Parameters:
  • name – name of the property
  • copy – if false (default) values are stored as is, otherwise new values are copied.
  • readwrite – If true (default) the property is read-write
  • type – an encoded type for the property, defaults to _C_ID.
  • iVarName – Name of the instance variable used to store the value. Default to the name of the property prefixed by and underscore.

This synthensizes a getter, and if necessary, setter method with the correct signature. The getter and setter provide access to an instance variable.

This can be used when specific semantics are required (such as copying values before storing them).

The class object_property provides simular features with a nicer python interface: with that calss the property behaves itself like a property for python code, with this function you still have to call accessor methods in your code.

Interacting with @synchronized blocks

PyObjC provides an API that implements locking in the same way as the @synchronized statement in Objective-C.

with object_lock(anNSObject):
    pass
class objc.object_lock(value)

This class represents the mutex that protects an Objective-C object for the @synchronized statement. This can be used as a context manager for the with statement, but can also be used standalone.

lock()

Acquire the object mutex

unlock()

Release the object mutex

Archiving Python and Objective-C objects

Python and Objective-C each provide a native object serialization method, the pickle module in Python and the NSCoding protocol in Objective-C.

It is possible to use an NSKeyedArchiver to store any Python object that can be pickled in an Objective-C serialized data object.

Due to technical details it is not possible to pickle an Objective-C object, unless someone explicitly implements the pickle protocol for such an object.

Properties

Introduction

Both Python and Objective-C have support for properties, which are object attributes that are accessed using attribute access syntax but which result in a method call.

The Python built-in property <__builtin__.property__ is used to define new properties in plain Python code. These properties don’t full interoperate with Objective-C code though because they do not necessarily implement the Objective-C methods that mechanisms like Key-Value Coding use to interact with a class.

PyObjC therefore has a number of property classes that allow you to define new properties that do interact fully with the Key-Value Coding and Observation frameworks.

class objc.object_property(name=None, read_only=False, copy=False, dynamic=False, ivar=None, typestr=_C_ID, depends_on=None)
Parameters:
  • name – Name of the property, the default is to extract the name from the class dictionary
  • read_only – Is this a read-only property? The default is a read-write property.
  • copy – Should the default setter method copy values? The default retains the new value without copying.
  • dynamic – If this argument is True the property will not generate default accessor, but will rely on some external process to create them.
  • ivar – Name of the instance variable that’s used to store the value. When this value is None the name will be calculated from the property name. If it is NULL there will be no instance variable.
  • typestr – The Objective-C type for this property, defaults to an arbitrary object.
  • depends_on – A sequence of names of properties the value of this property depends on.

During the class definition you can add accessor methods by using the property as a decorator

object_property.getter()

Decorator for defining the getter method for a property. The name of the method should be the same as the property:

class MyObject (NSObject):

    prop = objc.object_property()

    @prop.getter
    def prop(self):
       return 42
object_property.setter()

Decorator for defining the setter method for a property. The name of the method should be the same as the property.

object_property.validate()

Decorator for defining a Key-Value Coding validator for this property.

It is possible to override property accessor in a subclass:

class MySubclass (MyObject):
    @MyObject.prop.getter
    def getter(self):
        return "the world"

This can also be used to convert a read-only property to a read-write one by adding a setter accessor.

Properties for structured types

Key-Value Coding is slightly different for structured types like sets and lists (ordered and unordered collections). For this reason PyObjC also provides subclasses of object_property that are tuned for these types.

class objc.array_property

This property implements a list-like property. When you access the property you will get an object that implements the MutableSequence ABC, and that will generate the correct Key-Value Observation notifications when the datastructure is updated.

class objc.set_property

This property implements a set-like property. When you access the property you will get an object that implements the MutableSet ABC, and that will generate the correct Key-Value Observation notifications when the datastructure is updated.

class objc.dict_property

This property is like an object_property, but has an empty NSMutableDictionary object as its default value. This type is mostly provided to have a complete set of property types.

These collection properties are at this time experimental and do not yet provide proper hooks for tweaking their behavior. Future versions of PyObjC will provide such hooks (for example a method that will be called when an item is inserted in an array property).

Unconvertable pointer values

With incomplete metadata the bridge can run into pointer values that it cannot convert to normal Python values. When options.unknown_pointer_raises is false such pointer values are bridged as instances of ObjCPointer.

The bridge will unconditionally emit a warning before creating such instances, the reason for this is that the use of ObjCPointer is unwanted (that’s why the creation of such objects is disabled by default in PyObjC 3.0).

class objc.ObjCPointer
type

A bytes string with the Objective-C type encoding for the pointed to value.

pointerAsInteger

An integer value with the raw pointer value.