美文网首页
Runtime 之 使用场合及OC中的动态性

Runtime 之 使用场合及OC中的动态性

作者: 有梦想的狼 | 来源:发表于2020-03-05 11:08 被阅读0次

Runtime的使用场合

  • 利用关联对象(AssociatedObject)给分类添加属性
  • 遍历类的所有成员变量(修改textfield的占位文字颜色、字典转模型、自动归档解档)
    1.1. 修改textfield的占位文字颜色
    self.textField.placeholder = @"请输入用户名";
    [self.textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
    
    1.2. 字典转模型:
    id obj = [[self alloc] init];
    unsigned int count;
    Ivar *ivars = class_copyIvarList(self, &count);
    for (int i = 0; i < count; i++) {
      // 取出i位置的成员变量
        Ivar ivar = ivars[i];
        NSMutableString *name = [NSMutableString stringWithUTF8String:ivar_getName(ivar)];
        [name deleteCharactersInRange:NSMakeRange(0, 1)];      
        // 设值
        id value = json[name];
        if ([name isEqualToString:@"ID"]) {
          value = json[@"id"];
        }
        [obj setValue:value forKey:name];
    }
    free(ivars);
    
    1.3. 自动归档解档
    请参考:归档解档
  • 交换方法实现(交换系统的方法)
+ (void)load
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class cls = NSClassFromString(@"__NSDictionaryM");
        Method method1 = class_getInstanceMethod(cls, @selector(setObject:forKeyedSubscript:));
        Method method2 = class_getInstanceMethod(cls, @selector(mj_setObject:forKeyedSubscript:));
        method_exchangeImplementations(method1, method2);
        
        Class cls2 = NSClassFromString(@"__NSDictionaryI");
        Method method3 = class_getInstanceMethod(cls2, @selector(objectForKeyedSubscript:));
        Method method4 = class_getInstanceMethod(cls2, @selector(mj_objectForKeyedSubscript:));
        method_exchangeImplementations(method3, method4);
    });
}

- (void)mj_setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key
{
    if (!key) return;
    
    [self mj_setObject:obj forKeyedSubscript:key];
}

- (id)mj_objectForKeyedSubscript:(id)key
{
    if (!key) return nil;
    
    return [self mj_objectForKeyedSubscript:key];
}
  • 利用消息转发机制解决方法找不到的异常问题
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    // 本来能调用的方法
    if ([self respondsToSelector:aSelector]) {
        return [super methodSignatureForSelector:aSelector];
    }
    
    // 找不到的方法
    return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}

// 找不到的方法,都会来到这里
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    NSLog(@"%@中找不到%@方法", NSStringFromClass(anInvocation.target), NSStringFromSelector(anInvocation.selector));
}
  • 动态创建类等等

OC的动态性

  • OC是一门动态性比较强的编程语言,允许很多操作推迟到程序运行时再进行
  • OC的动态性就是由Runtime来支撑和实现的,Runtime是一套C语言的API,封装了很多动态性相关的函数
  • 平时编写的OC代码,底层都是转换成了Runtime API进行调用

相关文章

网友评论

      本文标题:Runtime 之 使用场合及OC中的动态性

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