Runtime应用

作者: Code_人生 | 来源:发表于2019-04-29 15:07 被阅读33次

实例一 创建类

    const char *clsName = [dataDict[@"class"] UTF8String];
    Class cls = objc_getClass(clsName);
    // 1: 创建类
    if (!cls) {
        Class superClass = [UIViewController class];
        cls  = objc_allocateClassPair(superClass, clsName, 0);
        class_addIvar(cls, "ending", sizeof(NSString *), log2(sizeof(NSString *)), @encode(NSString *));
        class_addIvar(cls, "show_lb", sizeof(UILabel *), log2(sizeof(UILabel *)), @encode(UILabel *));
        objc_registerClassPair(cls);
        
        Method method = class_getInstanceMethod([self class], @selector(lg_instancemethod));
        IMP methodIMP = method_getImplementation(method);
        const char *types = method_getTypeEncoding(method);
        BOOL rest = class_addMethod(cls, @selector(viewDidLoad), methodIMP, types);
        NSLog(@"rest == %d",rest);
    }

    // 实例化对象
    id instance = nil;
    @try {
        UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
        instance = [sb instantiateViewControllerWithIdentifier:dataDict[@"class"]];
    } @catch (NSException *exception) {
        
        instance = [[cls alloc] init];
    } @finally {
        NSLog(@"OK");
    }
    
    NSDictionary *dict = dataDict[@"data"];
    [dict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        // 检测是否存在key的属性
        if (class_getProperty(cls, [key UTF8String])) {
            [instance setValue:obj forKey:key];
        }
        // 检测是否存在key的变量
        else if (class_getInstanceVariable(cls, [key UTF8String])){
            [instance setValue:obj forKey:key];
        }
    }];
    
    [self.navigationController pushViewController:instance animated:YES];

实例二 编码解码

@interface LGPerson : NSObject<NSSecureCoding>
@end

#import "LGPerson.h"
#import <objc/runtime.h>

@implementation LGPerson

- (void)encodeWithCoder:(NSCoder *)aCoder {
    
    unsigned int count = 0;
    Ivar* ivars = class_copyIvarList([self class], &count);
    
    for (int i = 0; i < count; i++) {
        Ivar var = ivars[i];
        const char* name = ivar_getName(var);
        NSString* key = [NSString stringWithUTF8String:name];
        id value = [self valueForKey:key];
        [aCoder encodeObject:value forKey:key];
    }
    free(ivars);
}


- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
    
    if (self == [super init]) {
        unsigned int count = 0;
        Ivar* ivars = class_copyIvarList([self class], &count);
        
        for (int i = 0; i < count; i++) {
            Ivar var = ivars[i];
            const char* name = ivar_getName(var);
            NSString* key = [NSString stringWithUTF8String:name];
            id value = [aDecoder decodeObjectForKey:key];
            [self setValue:value forKey:key];
        }
        free(ivars);
    }
    return self;
}

+ (BOOL)supportsSecureCoding{
    return YES;
}
@end

实例三 方法交换

#import "ViewController+LGHook.h"
#import <objc/runtime.h>

@implementation ViewController (LGHook)

+ (void)load {
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Method m1 = class_getInstanceMethod(self, @selector(viewWillAppear:));
        Method m2 = class_getInstanceMethod(self, @selector(lg_viewWillAppear:));
        method_exchangeImplementations(m1, m2);
    });
    
}

- (void)lg_viewWillAppear:(BOOL) animated {
    NSLog(@"%s", __func__);
    [self lg_viewWillAppear:animated];
}

@end

相关文章

网友评论

    本文标题:Runtime应用

    本文链接:https://www.haomeiwen.com/subject/qtbynqtx.html