Skip to content

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

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 hard-coded locations, as a fallback for systems where find_library does not work (such as iOS).

rubicon.objc.runtime.libc module-attribute

libc = load_library('c')

The C standard library.

The following functions are accessible by default:

  • free

rubicon.objc.runtime.libobjc module-attribute

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 module-attribute

Foundation = load_library('Foundation')

The Foundation framework.

Objective-C runtime types

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

rubicon.objc.runtime.objc_id

Bases: c_void_p

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

rubicon.objc.runtime.objc_block

Bases: objc_id

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.

rubicon.objc.runtime.SEL

SEL(init=None)

Bases: c_void_p

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 property

name: bytes

The selector's name as bytes.

rubicon.objc.runtime.Class

Bases: objc_id

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

rubicon.objc.runtime.IMP

Bases: c_void_p

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.

rubicon.objc.runtime.Method

Bases: c_void_p

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

rubicon.objc.runtime.Ivar

Bases: c_void_p

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

rubicon.objc.runtime.objc_property_t

Bases: c_void_p

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

rubicon.objc.runtime.objc_property_attribute_t

Bases: Structure

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

name property

name: bytes

The attribute name as a C string (bytes).

value property

value: bytes

The attribute value as a C string (bytes).

rubicon.objc.runtime.objc_method_description

Bases: Structure

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

name property

name: SEL

The method name as a SEL.

types property

types: bytes

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

rubicon.objc.runtime.objc_super

Bases: Structure

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

receiver property

receiver: objc_id

The receiver of the call, as an objc_id.

super_class property

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

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

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

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

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

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:] <https://developer.apple.com/documentation/foundation/nsstring/stringwithformat:?language=objc>_. When using :func: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")],
)
PARAMETER DESCRIPTION
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.

DEFAULT: ()

restype

The return type of the method.

argtypes

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

DEFAULT: None

varargs

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

DEFAULT: None

rubicon.objc.runtime.send_super

send_super(
    cls,
    receiver,
    selector,
    *args,
    restype=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 beeware/rubicon-objc#107 and PR beeware/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.

PARAMETER DESCRIPTION
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.

DEFAULT: ()

restype

The return type of the method.

DEFAULT: c_void_p

argtypes

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

DEFAULT: None

varargs

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

DEFAULT: None

rubicon.objc.runtime.add_method

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.

PARAMETER DESCRIPTION
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.

DEFAULT: False

RETURNS DESCRIPTION

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

add_ivar(cls, name, vartype)

Add a new instance variable of type vartype to cls.

rubicon.objc.runtime.get_ivar

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

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.