This document gives an overview of the PyObjC for developers (of the package).
One of the sections describes how all of it works, and some of the limitations.
This document is a incomplete, it should be updated.
Classes are scanned for methods when the Python wrapper for a class is created. We then create Python wrappers for those methods. This way users can use the normal Python introspection methods to check which methods are available.
There are several occasions when these method tables are rescanned, because classes can grow new methods when categories are loaded into the runtime. Additionally, it is known that some Cocoa frameworks in Mac OS X change their method tables when the first instance is created.
It is possible to subclass Objective-C classes from Python. These classes end up in a structure containing both a Python type object and an Objective-C class. Instances of these classes also contain both a Python instance and an Objective-C object.
The first Python subclass of an Objective-C class introduces a new instance
variable in the Objective-C object to store the pointer to the Python half of
the cluster. This variable is always referenced by name. The Python half is
a subclass of objc_object
that already contains a pointer to an Objective-C
object. This first subclass also introduces a number of class and instance
methods that the PyObjC bridge uses to maintain the illusion of a single
object on both sides. Check class-builder.m for details.
Documentation
Example scripts and applets.
The pure Python parts of the packages that comprise PyObjC. Currently contains the packages 'objc', 'PyObjCScripts', 'PyObjCTools' and the semi-automatically generated wrappers for the 'AddressBook', 'AppKit', 'ExceptionHandling', 'Foundation', 'InterfaceBuilder', 'Message', 'PreferencePanes', 'ScreenSaver', 'SecurityInterface' and 'WebKit' frameworks.
Extension modules related to the packages in 'Lib'.
Scripts used during building and/or development of PyObjC.
Resources used for building the Apple Installer packages.
Project Builder templates and syntax specifications for PyObjC development.
Xcode templates for PyObjC development.
A local copy of libffi, the Foreign Function Interface library used by PyObjC.
Modules used by setup.py for building and distributing PyObjC.
Local copies of Python packages and modules used by PyObjC that are not expected to be found in the minimum supported version of Python. These are not automatically installed by setup.py, but some may be included in a bdist_mpkg installer (currently, just py2app).
The Objective-C rules for reference counts are pretty easy: A small number
of class methods (alloc
, allocWithZone:
, copy
, ...) transfer
object ownership to the caller. For all other objects you have to call
retain
if you want to keep a reference. This includes all factory
methods, such as [NSString stringWithCString:"bla"]
!
When programming Cocoa in Python, you rarely need to worry about
reference counts: the objc
module makes this completely transparent to
user. This is mostly implemented in [de]pythonify_c_value
. Additonal
code is needed when calling methods that transfer ownership of their return
value (as described above) and when updating a instance variable in an
Objective-C object (retain new and release old, in that order). Both are
implemented.
Python unicode
instances are automatically converted to NSString
and
back. An NSString
is represented in Python as a subtype of unicode
:
objc.pyobjc_unicode
. This performs a conversion, because Python's
unicode
type is immutable, but it also maintains a reference to the
original NSString
. Currently, the conversion is done using UTF-8 for
exchange, because the internal representation of unicode
is dependent on
compile time settings.
The original, unwrapped, NSString
instance is accessible from Python
with the nsstring()
method of objc.pyobjc_unicode
, primarily used
to access an updated copy of an NSMutableString
's contents. Since
PyObjC 1.2, NSString
and NSMutableString
methods are available from
the objc.pyobjc_unicode
object, though they do not show up via Python's
introspection mechanisms.
For legacy and convenience, Python str
instances are automatically coerced
to unicode
when they cross the bridge using the same mechanism that
automatically converts from str
to unicode
(using
sys.getdefaultencoding()
). This automatic conversion can cause terrible
things to happen at runtime that are hard to test for, so you may enable an
objc.PyObjCStrBridgeWarning
at each coercion attempt by calling
objc.setStrBridgeEnabled(False)
. To promote this warning to an exception,
see the documentation for the warnings
module in the standard library.