美文网首页
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