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 CDLL
s. 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 hard-coded locations, as a fallback for systems wherefind_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_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
orstr
object to obtain a selector with that value.(The normal arguments supported by
c_void_p
are still accepted.)
- 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 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>
.
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 thelibobjc
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 usingsend_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 separatevarargs
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 takevarargs
. 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 theargtypes
list. Instead, the values are automatically converted to C types using the defaultctypes
argument conversion rules. To ensure that allvarargs
are converted to the expected C types, it is recommended to manually convert allvarargs
toctypes
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
orobjc_id
.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 defaultctypes
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 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 currentclass
block. 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 beeware/rubicon-objc#107 and PR beeware/rubicon-objc#108.Although it is possible to pass other values than
__class__
andself
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 anObjCClass
orClass
.receiver – The object on which to call the method, as an
ObjCInstance
,objc_id
, orc_void_p
.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 defaultctypes
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
orClass
.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 implicitself
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 aValueError
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
tocls
.
- rubicon.objc.runtime.get_ivar(obj, varname, weak=False)¶
Get the value of obj’s
ivar
namedvarname
.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 theivar
’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 theivar
’s value.For object types, the returned data object is independent of the
ivar
’s memory. This is because objectivars
may be weak, and thus cannot always be accessed directly by their address.