It is pretty rare to actually have to dive into the objc-runtime for any day to day coding. Most developers wont have to touch the runtime, however it is helpful to know what is possible and be able to use it if required. The objective-c runtime is written in C and is how the underlying parts of the objective-c language work including message sending, ivars and properties. This post shows an example of where I have used the Objective-C runtime in one of my projects.
One example of where I have used the runtime in my projects is the validation code in DBValidator
. The validation code is implemented as a category on NSObject
called NSObject+DBValidator
. This is so we can add validation rules to any objective-c object. The only problem with this approach is that you can’t add any properties or ivars to an object using a category.
We can work around this limitation by using the objective-c runtime directly.
Below is the implementation of the NSObject+DBValidator
category:
We have a @property
defined in the header called validationRules
and we override both the setter and getter in the implementation. In the setValidationRules:
method we use a C function from the objective-c runtime called objc_setAssociatedObject
. This function allows us to set a reference on the self
object. We give it a key, the object (in this case the validationRules
passed to the method) and the association policy.
The valid options for the association policy are:
enum {
OBJC_ASSOCIATION_ASSIGN = 0,
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
OBJC_ASSOCIATION_RETAIN = 01401,
OBJC_ASSOCIATION_COPY = 01403
};
Notice how these options map directly to @property
storage options! We are using OBJC_ASSOCIATION_RETAIN_NONATOMIC
because we want our NSObject
to retain the validation rules that are set on it.
In our validationRules
method, we use a similar call from the objective-c runtime called objc_getAssociatedObject
. This allows us to retrieve the object we set a reference to in the preious method. We have to pass the parent object and the key for the associated object we want. We return an empty array if validation rules are not yet set for this object.
Check out the full source code in the DBValidator GitHub Project