I know iOS Runtime is powerful and I have a question: where should we use runtime?
For example, I find many articles will discuss about class & method swizzling. And in which case should I use it?
I also google it and find it is widely used in jailbroken development. However, I'm a non-jailbroken developer, please don't cover jailbroken~
Thanks!
It's a very general question. The runtime is a library linked with your programs that implements part of Objective-C so it may show up anywhere. If you have to ask, don't use it. But FYI here are some common uses:
Swizzling is the exchange of the identifiers of two methods so they point to each other’s implementations. Both methods are still available.
It's useful to use swizzling instead categories to preserve the original implementation of the method, and to avoid having two categories overriding the same method (the result would be undefined).
See https://stackoverflow.com/a/8636521/412916 for a list of dangers.
See https://stackoverflow.com/a/13646650/412916
An associative reference is a way to add an instance variable to an object without changing its code. The associative reference is automatically removed when the object is deallocated.
Google it.
Introspect the properties of the classes. For example to map between JSON and a plain class of your model. I guess Mantle and the Overcoat wrapper are examples of this.
You should read the Objective-C Runtime Programming Guide.
This is probably the most important use. The code is not mine and I don't remember the original author.
#include <objc/runtime.h>
#import <Foundation/Foundation.h>
@interface A: NSObject
@end
@implementation A
void pileOfPoo(id self, SEL _cmd) {
NSLog(@"💩");
}
+ (BOOL)resolveInstanceMethod: (SEL)name {
if ([NSStringFromSelector(name) isEqualToString: @"💩"]) {
class_addMethod([self class], name, (IMP)pileOfPoo, "v@:");
return YES;
} else return NO;
}
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
A *a = [[A alloc] init];
SEL aSelector = NSSelectorFromString(@"💩");
[a performSelector: aSelector];
}
return 0;
}
Generally it shouldn't be used. When it is used it should be done with great care as the risk of breaking everything is high when you make a mistake. Usually it should only be done in well used code, preferably maintained as an open-source project so that many people check the validity.
It's not only used for jailbreak, but it does generally involve private classes / methods and allows you to workaround / expand limitations in the APIs. But it can also be used to expand by, for example, inserting your own class as an observer in some relationship so it can take some action and then forward the information to the 'true' observer (AFNetworking used to do this).
Generally you should use features like categories or standard subclasses to add functionality.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With