Source

pyobjc / pyobjc-core / Doc / api / module-objc.rst

Full commit

:mod:`objc` -- The PyObjC bridge

Introduction

The module :mod:`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 :mod:`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.

Debugging

Tweaking behaviour

Utilities

Accessing classes and protocols

Dynamic modification of classes

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

Usage:

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

The metaclass uses :func:`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 :class:`Category`.

Plugin bundles

Memory management

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

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.

Framework wrappers

Types

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

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.

Note

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

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

Methods of the underlying :c:type:`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.

Warning

Instances of :c:type:`NSString` can be mutable. Mutations to mutable Cocoa strings are not reflected in instances of :class:`pyobjc_unicode`, use :meth:`nsstring` and explict conversion to the built-in unicode type when you work with mutable :c:type:`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 :func:`open`).

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

param function:The Python callable that is used for the method. Can be a :class:`classmethod` , but not a :class:`staticmethod`.
param selector:The Objective-C selector for the method. The default is calculated from the __name__ attribute for function
param 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).
param isClassMethod:
 Used to specify if a method is a class method (default is :data:`True` if function is a :class:`classmethod` and :data:`False` otherwise)
param returnType:
 Alternative method for specifying the method return type, using the syntax of :c:func:`Py_BuildValue`.
param argumentTypes:
 Alternative method for specifying argument types, using the syntax of :c:func:`Py_BuildValue`.
param isRequired:
 Specify if the method is required (defaults to :data:`True`), used in the definition of protocols.

The arguments returnType and argumentTypes are deprecated in PyObjC 2.5, they are confusing and can only specify a subset of types.

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.

param name:Name of the instance variable. The name defaults to the name the instance variable is bound to in a class definition.
param type:Type encoding for the instance varialble. Defaults to :data:`_C_ID` (that is, an object)
param isOutlet:If :data:`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 :class:`ivar` have a number of attributes that help with introspection:

  • __typestr__: The type encoding of the Objective-C type of the variable
  • __name__: The Objective-C name of the variable
  • __isOutlet__: :data:`True` if the variable is an :func:`IBOutlet`
  • __isSlot__: :data:`True` if the variable is a Python slot.

Note

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

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.

param name:Name of the protocol
param selector_list:
 A sequence of :class:`selector` instances, all of which should have no callable.

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

param name:The name of the protocol
param supers:A list of protocols this protocol inherits from
param selector_list:
 A sequence of :class:`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)

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.

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 :class:`varlist` object can easily read 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.

Instances of this class represent global functions from Cocoa frameworks. These objects are created using :func:`loadBundleFunctions` and :func:`loadFunctionList`.

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.

This is a subclass of :class:`super <__builtin__.super>` that works properly for Objective-C classes as well as regular Python classes.

Note

The statement :samp:`from {Framework} import \*` will replace the built-in :class:`super <__builtin__.super>` by this class.

Constants

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 :class:`bytes` in Python 3.x and :class:`str` in Python 2.x).

Complex types

More complex types can be represented using longer type strings:

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 :const:`_C_IN`.
  • When a pointer argument is an output argument it is prefixed by :const:`_C_OUT`.
  • When a pointer argument is an input and output argument it is prefixed by :const:`_C_INOUT`.
  • Distributed objects uses the prefix :const:`_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 :const:`_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 :const:`_C_IN`, :const:`_C_OUT` or :const:`_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.

TODO: Write how to write Objective-C code to ensure that the right prefixes are added by the compiler.

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
:const:`_C_CFTYPEID` :c:type:`CFTypeID`
:const:`_C_NSInteger` :c:type:`NSInteger`
:const:`_C_NSUInteger` :c:type:`NSUInteger`
:const:`_C_CFIndex` :c:type:`CFIndex`
:const:`_C_CGFloat` :c:type:`CGFloat`
:const:`_sockaddr_type` :c:type:`struct sockaddr`

Context pointers

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

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

Descriptors

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

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.

Archiving Python and Objective-C objects

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

It is possible to use an :c:type:`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 :class:`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.

TODO: Implement method for enabling properties on existing classes and tell why that is off by default and when it will be turned on by default.

TODO: The description is way to minimal, even the design document contained more information.

param name:Name of the property, the default is to extract the name from the class dictionary
param read_only:
 Is this a read-only property? The default is a read-write property.
param copy:Should the default setter method copy values? The default retains the new value without copying.
param dynamic:If this argument is :data:`True` the property will not generate default accessor, but will rely on some external process to create them.
param ivar:Name of the instance variable that's used to store the value. When this value is :data:`None` the name will be calculated from the property name. If it is :data:`NULL` there will be no instance variable.
param typestr:The Objective-C type for this property, defaults to an arbitrary object.
param 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

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 :class:`object_property` that are tuned for these types.

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

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

This property is like an :class:`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).