iOS RunTime:用例

sco*_*ozj 5 runtime objective-c ios

我知道iOS Runtime很强大,我有一个问题:我们应该在哪里使用运行时?

例如,我发现许多文章将讨论类和方法的混合.在哪种情况下我应该使用它?

我也谷歌它发现它被广泛用于越狱开发.但是,我是一个非越狱的开发者,请不要越狱〜

谢谢!

Jan*_*ano 7

这是一个非常普遍的问题.运行时是一个与您的程序链接的库,它实现了Objective-C的一部分,因此它可以显示在任何地方.如果你不得不问,不要使用它.但是,这里有一些常见的用途:

混写

Swizzling是两种方法的标识符的交换,因此它们指向彼此的实现.这两种方法仍然可用.

使用swizzling而不是类别来保留方法的原始实现是有用的,并避免让两个类重写相同的方法(结果将是未定义的).

有关危险列表,请参阅/sf/answers/604556501/.

动态方法(有点)

请参阅/sf/answers/955265531/

关联参考

关联引用是一种在不更改代码的情况下将实例变量添加到对象的方法.取消分配对象时,将自动删除关联引用.

谷歌吧.

内省

反思类的属性.例如,在JSON和模型的普通类之间进行映射.我猜Mantle大衣包装就是这方面的例子.

您应该阅读Objective-C运行时编程指南.

使用表情符号作为方法名称

这可能是最重要的用途.代码不是我的,我不记得原作者.

#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;
}
Run Code Online (Sandbox Code Playgroud)