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_addIvarclass_addMethodclass_addPropertyclass_addProtocolclass_copyIvarListclass_copyMethodListclass_copyPropertyListclass_copyProtocolListclass_getClassMethodclass_getClassVariableclass_getInstanceMethodclass_getInstanceSizeclass_getInstanceVariableclass_getIvarLayoutclass_getMethodImplementationclass_getNameclass_getPropertyclass_getSuperclassclass_getVersionclass_getWeakIvarLayoutclass_isMetaClassclass_replaceMethodclass_respondsToSelectorclass_setIvarLayoutclass_setVersionclass_setWeakIvarLayoutivar_getNameivar_getOffsetivar_getTypeEncodingmethod_exchangeImplementationsmethod_getImplementationmethod_getName
method_getTypeEncodingmethod_setImplementationobjc_allocateClassPairobjc_copyProtocolListobjc_getAssociatedObjectobjc_getClassobjc_getMetaClassobjc_getProtocolobjc_registerClassPairobjc_removeAssociatedObjectsobjc_setAssociatedObjectobject_getClassobject_getClassNameobject_getIvarobject_setIvarproperty_getAttributesproperty_getNameproperty_copyAttributeListprotocol_addMethodDescriptionprotocol_addProtocolprotocol_addPropertyobjc_allocateProtocolprotocol_conformsToProtocolprotocol_copyMethodDescriptionListprotocol_copyPropertyListprotocol_copyProtocolListprotocol_getMethodDescriptionprotocol_getNameobjc_registerProtocolsel_getNamesel_isEqualsel_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
ValueErroris 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 wherefind_librarydoes 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_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
bytesorstrobject to obtain a selector with that value. (The normal arguments supported byc_void_pare still accepted.)- name¶
The selector’s name as
bytes.
- class rubicon.objc.runtime.IMP([value])¶
The IMP type from
<objc/objc.h>.An
IMPcannot be called directly — it must be cast to the correctCFUNCTYPE()first, to provide the necessary information about its signature.
- 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>.
- class rubicon.objc.runtime.objc_method_description([name, value])¶
The objc_method_description structure from
<objc/runtime.h>.- types¶
The method’s signature encoding as a C string (
bytes).
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
libobjcfunction 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 thelibobjcfunction if available, and otherwise emulates it.
- rubicon.objc.runtime.get_class(name)¶
Get the Objective-C class with the given name as a
Classobject.If no class with the given name is loaded,
Noneis 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_streton the current system.
- rubicon.objc.runtime.should_use_fpret(restype)¶
Return whether a method returning the given type must be called using
objc_msgSend_fpreton the current system.
- rubicon.objc.runtime.send_message(receiver, selector, *args, restype, argtypes, 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 separatevarargskeyword 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
argtypeslist. Instead, the values are automatically converted to C types using the defaultctypesargument conversion rules. To ensure that all varargs are converted to the expected C types, it is recommended to manually convert all varargs toctypestypes 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
ObjCInstanceorobjc_id.selector – The name of the method as a
str,bytes, orSEL.args – The method arguments.
restype – The return type of the method.
argtypes – The argument types of the method, as a
list.varargs – Variadic arguments for the method, as a
list. Defaults to[]. These arguments are converted according to the defaultctypesconversion rules.
- rubicon.objc.runtime.send_super(cls, receiver, selector, *args, restype=<class 'ctypes.c_void_p'>, argtypes=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 classcls.In practice, the first parameter should always be the special variable
__class__, and the second parameter should beself. A typicalsend_super()call would besend_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 currentclassblock. The exact reasons why__class__must be passed manually are somewhat technical, and are not directly relevant to users ofsend_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__andselffor 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
supercall is happening, as anObjCClassorClass.receiver – The object on which to call the method, as an
ObjCInstance,objc_id, orc_void_p.selector – The name of the method as a
str,bytes, orSEL.args – The method arguments.
restype – The return type of the method. Defaults to
c_void_p.argtypes – The argument types of the method, as a
list. Defaults to an empty list (i. e. all arguments are treated as C varargs).
- 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
ObjCClassorClass.selector – The name for the new method, as a
str,bytes, orSEL.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 implicitselfand_cmdparameters 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 aValueErrorerror 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
ctypesdata object.For non-object types (everything except
objc_idand 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
weakisTrue, only a weak reference to the value is stored.value must be a
ctypesdata object whose type matches that of the ivar.