rubicon.objc.runtime — Low-level Objective-C runtime access

This module contains types, functions, and C libraries used for low-level access to the Objective-C runtime.

In most cases there is no need to use this module directly — the rubicon.objc.api module provides the same functionality through a high-level interface.

C libraries

Some commonly used C libraries are provided as CDLLs. Other libraries can be loaded using the load_library() function.

rubicon.objc.runtime.libc = load_library('c')

The C standard library.

The following functions are accessible by default:

  • free

rubicon.objc.runtime.libobjc = load_library('objc')

The Objective-C runtime library.

The following functions are accessible by default:

  • class_addIvar

  • class_addMethod

  • class_addProperty

  • class_addProtocol

  • class_copyIvarList

  • class_copyMethodList

  • class_copyPropertyList

  • class_copyProtocolList

  • class_getClassMethod

  • class_getClassVariable

  • class_getInstanceMethod

  • class_getInstanceSize

  • class_getInstanceVariable

  • class_getIvarLayout

  • class_getMethodImplementation

  • class_getName

  • class_getProperty

  • class_getSuperclass

  • class_getVersion

  • class_getWeakIvarLayout

  • class_isMetaClass

  • class_replaceMethod

  • class_respondsToSelector

  • class_setIvarLayout

  • class_setVersion

  • class_setWeakIvarLayout

  • ivar_getName

  • ivar_getOffset

  • ivar_getTypeEncoding

  • method_exchangeImplementations

  • method_getImplementation

  • method_getName

  • method_getTypeEncoding

  • method_setImplementation

  • objc_allocateClassPair

  • objc_copyProtocolList

  • objc_getAssociatedObject

  • objc_getClass

  • objc_getMetaClass

  • objc_getProtocol

  • objc_registerClassPair

  • objc_removeAssociatedObjects

  • objc_setAssociatedObject

  • object_getClass

  • object_getClassName

  • object_getIvar

  • object_setIvar

  • property_getAttributes

  • property_getName

  • property_copyAttributeList

  • protocol_addMethodDescription

  • protocol_addProtocol

  • protocol_addProperty

  • objc_allocateProtocol

  • protocol_conformsToProtocol

  • protocol_copyMethodDescriptionList

  • protocol_copyPropertyList

  • protocol_copyProtocolList

  • protocol_getMethodDescription

  • protocol_getName

  • objc_registerProtocol

  • sel_getName

  • sel_isEqual

  • sel_registerName

rubicon.objc.runtime.Foundation = load_library('Foundation')

The Foundation framework.

rubicon.objc.runtime.load_library(name)

Load and return the C library with the given name.

If the library could not be found, a ValueError is raised.

Internally, this function uses ctypes.util.find_library() to search for the library in the system-standard locations. If the library cannot be found this way, it is attempted to load the library from certain hardcoded locations, as a fallback for systems where find_library does not work (such as iOS).

Objective-C runtime types

These are various types used by the Objective-C runtime functions.

class rubicon.objc.runtime.objc_id([value])

The id type from <objc/objc.h>.

class rubicon.objc.runtime.objc_block([value])

The low-level type of block pointers.

This type tells Rubicon’s internals that the object in question is a block and not just a regular Objective-C object, which affects method argument and return value conversions. For more details, see Objective-C blocks.

Note

This type does not correspond to an actual C type or Objective-C class. Although the internal structure of block objects is documented, as well as the fact that they are Objective-C objects, they do not have a documented type or class name and are not fully defined in any header file.

Aside from the special conversion behavior, this type is equivalent to objc_id.

class rubicon.objc.runtime.SEL([value])

The SEL type from <objc/objc.h>.

The constructor can be called with a bytes or str object to obtain a selector with that value. (The normal arguments supported by c_void_p are still accepted.)

name

The selector’s name as bytes.

class rubicon.objc.runtime.Class([value])

The Class type from <objc/objc.h>.

class rubicon.objc.runtime.IMP([value])

The IMP type from <objc/objc.h>.

An IMP cannot be called directly — it must be cast to the correct CFUNCTYPE() first, to provide the necessary information about its signature.

class rubicon.objc.runtime.Method([value])

The Method type from <objc/runtime.h>.

class rubicon.objc.runtime.Ivar([value])

The Ivar type from <objc/runtime.h>.

class rubicon.objc.runtime.objc_property_t([value])

The objc_property_t type from <objc/runtime.h>.

class rubicon.objc.runtime.objc_property_attribute_t([name, value])

The objc_property_attribute_t structure from <objc/runtime.h>.

name
value

The attribute name and value as C strings (bytes).

class rubicon.objc.runtime.objc_method_description([name, value])

The objc_method_description structure from <objc/runtime.h>.

name

The method name as a SEL.

types

The method’s signature encoding as a C string (bytes).

class rubicon.objc.runtime.objc_super([receiver, super_class])

The objc_super structure from <objc/message.h>.

receiver

The receiver of the call, as an objc_id.

super_class

The class in which to start searching for method implementations, as a Class.

Objective-C runtime utility functions

These utility functions provide easier access from Python to certain parts of the Objective-C runtime.

rubicon.objc.runtime.object_isClass(obj)

Return whether the given Objective-C object is a class (or a metaclass).

This is equivalent to the libobjc function object_isClass from <objc/runtime.h>, which is only available since OS X 10.10 and iOS 8. This module-level function is provided to support older systems — it uses the libobjc function if available, and otherwise emulates it.

rubicon.objc.runtime.get_class(name)

Get the Objective-C class with the given name as a Class object.

If no class with the given name is loaded, None is returned, and the Objective-C runtime will log a warning message.

rubicon.objc.runtime.should_use_stret(restype)

Return whether a method returning the given type must be called using objc_msgSend_stret on the current system.

rubicon.objc.runtime.should_use_fpret(restype)

Return whether a method returning the given type must be called using objc_msgSend_fpret on the current system.

rubicon.objc.runtime.send_message(receiver, selector, *args, restype, argtypes=None, varargs=None)

Call a method on the receiver with the given selector and arguments.

This is the equivalent of an Objective-C method call like [receiver sel:args].

Note

Some Objective-C methods take variadic arguments (varargs), for example +[NSString stringWithFormat:]. When using send_message(), variadic arguments are treated differently from regular arguments: they are not passed as normal function arguments in *args, but as a list in a separate varargs keyword argument.

This explicit separation of regular and variadic arguments protects against accidentally passing too many arguments into a method. By default these extra arguments would be considered varargs and passed on to the method, even if the method in question doesn’t take varargs. Because of how the Objective-C runtime and most C calling conventions work, this error would otherwise be silently ignored.

The types of varargs are not included in the argtypes list. Instead, the values are automatically converted to C types using the default ctypes argument conversion rules. To ensure that all varargs are converted to the expected C types, it is recommended to manually convert all varargs to ctypes types instead of relying on automatic conversions. For example:

send_message(
    NSString, "stringWithFormat:",
    at("%i %s %@"),
    restype=objc_id, argtypes=[objc_id],
    varargs=[c_int(123), cast(b"C string", c_char_p), at("ObjC string")],
)
Parameters
  • receiver – The object on which to call the method, as an ObjCInstance or objc_id.

  • selector – The name of the method as a str, bytes, or SEL.

  • args – The method arguments.

  • restype – The return type of the method.

  • argtypes – The argument types of the method, as a list. Defaults to [].

  • varargs – Variadic arguments for the method, as a list. Defaults to []. These arguments are converted according to the default ctypes conversion rules.

rubicon.objc.runtime.send_super(cls, receiver, selector, *args, restype=<class 'ctypes.c_void_p'>, argtypes=None, varargs=None, _allow_dealloc=False)

In the context of the given class, call a superclass method on the receiver with the given selector and arguments.

This is the equivalent of an Objective-C method call like [super sel:args] in the class cls.

In practice, the first parameter should always be the special variable __class__, and the second parameter should be self. A typical send_super() call would be send_super(__class__, self, 'init') for example.

The special variable __class__ is defined by Python and stands for the class object that is being created by the current class block. The exact reasons why __class__ must be passed manually are somewhat technical, and are not directly relevant to users of send_super(). For a full explanation, see issue pybee/rubicon-objc#107 and PR pybee/rubicon-objc#108.

Although it is possible to pass other values than __class__ and self for the first two parameters, this is strongly discouraged. Doing so is not supported by the Objective-C language, and relies on implementation details of the superclasses.

Parameters
  • cls – The class in whose context the super call is happening, as an ObjCClass or Class.

  • receiver – The object on which to call the method, as an ObjCInstance, objc_id, or c_void_p.

  • selector – The name of the method as a str, bytes, or SEL.

  • args – The method arguments.

  • restype – The return type of the method.

  • argtypes – The argument types of the method, as a list. Defaults to [].

  • varargs – Variadic arguments for the method, as a list. Defaults to []. These arguments are converted according to the default ctypes conversion rules.

rubicon.objc.runtime.add_method(cls, selector, method, encoding, replace=False)

Add a new instance method to the given class.

To add a class method, add an instance method to the metaclass.

Parameters
  • cls – The Objective-C class to which to add the method, as an ObjCClass or Class.

  • selector – The name for the new method, as a str, bytes, or SEL.

  • method – The method implementation, as a Python callable or a C function address.

  • encoding – The method’s signature (return type and argument types) as a list. The types of the implicit self and _cmd parameters must be included in the signature.

  • replace – If the class already implements a method with the given name, replaces the current implementation if True. Raises a ValueError error otherwise.

Returns

The ctypes C function pointer object that was created for the method’s implementation. This return value can be ignored. (In version 0.4.0 and older, callers were required to manually keep a reference to this function pointer object to ensure that it isn’t garbage-collected. Rubicon now does this automatically.)

rubicon.objc.runtime.add_ivar(cls, name, vartype)

Add a new instance variable of type vartype to cls.

rubicon.objc.runtime.get_ivar(obj, varname, weak=False)

Get the value of obj’s ivar named varname.

The returned object is a ctypes data object.

For non-object types (everything except objc_id and subclasses), the returned data object is backed by the ivar’s actual memory. This means that the data object is only usable as long as the “owner” object is alive, and writes to it will directly change the ivar’s value.

For object types, the returned data object is independent of the ivar’s memory. This is because object ivars may be weak, and thus cannot always be accessed directly by their address.

rubicon.objc.runtime.set_ivar(obj, varname, value, weak=False)

Set obj’s ivar varname to value. If weak is True, only a weak reference to the value is stored.

value must be a ctypes data object whose type matches that of the ivar.