5

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!

scorpiozj
  • 2,687
  • 5
  • 34
  • 60

3 Answers3

7

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;
}
Community
  • 1
  • 1
Jano
  • 62,815
  • 21
  • 164
  • 192
1

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.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • I strongly disagree with almost everything written here. What do you mean it uses private classes / methods? It's a public framework, documented by many apple docs. Stuff like associated objects or operations on properties of given classes (*class_copyPropertyList* etc) are not that complicated, and are really powerful tools. – Peter Sarnowski Oct 11 '13 at 12:21
  • I didn't say it uses private APIs, I said it is often used to interact with / change the response of private APIs. I also give an example of a perfectly 'legal' and useful use case which has nothing to do with private APIs. I also don't deny that these methods are very powerful, but they won't often be used by most programmers as that kind of introspective code isn't often required. Going out and looking for use cases is an interesting play activity but you should take care when using in production environments. @PeterSarnowski – Wain Oct 11 '13 at 13:17
0

Method swizzling in runtime is a good measure to 'hook' methods whatever you want. Why do we need hooking? There are all kinds of application of hooking, such as user behavior statistic, automatic serialization and so on.
Here we take user behavior as a sample. With help of method swizzling, we can hook 'viewWillAppear' method in any UIViewController subclass. That means we can know when 'viewWillAppear' is called and thus we can inject user behavior codes(e.g. page visiting count, page visiting duration) before or after 'viewWillAppear' method. In summary, with help of method swizzling, we can easily make user behavior statistic realized. Other kinds of application are the same.

ZilinWeng
  • 63
  • 8