Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS RunTime: Use Case [closed]

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!

like image 282
scorpiozj Avatar asked Oct 11 '13 08:10

scorpiozj


2 Answers

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

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.

Dynamic methods (sort of)

See https://stackoverflow.com/a/13646650/412916

Associative references

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.

Introspection

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.

Using emoji as a method name

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;
}
like image 102
Jano Avatar answered Oct 17 '22 01:10

Jano


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.

like image 1
Wain Avatar answered Oct 17 '22 01:10

Wain