iOS Runtime详解(新手也看得懂)

2020-01-21 07:51:57刘景俊

核心方法:在Model的基类中重写方法:


- (id)initWithCoder:(NSCoder *)aDecoder {
  if (self = [super init]) {
    unsigned int outCount;
    Ivar * ivars = class_copyIvarList([self class], &outCount);
    for (int i = 0; i < outCount; i ++) {
      Ivar ivar = ivars[i];
      NSString * key = [NSString stringWithUTF8String:ivar_getName(ivar)];
      [self setValue:[aDecoder decodeObjectForKey:key] forKey:key];
    }
  }
  return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
  unsigned int outCount;
  Ivar * ivars = class_copyIvarList([self class], &outCount);
  for (int i = 0; i < outCount; i ++) {
    Ivar ivar = ivars[i];
    NSString * key = [NSString stringWithUTF8String:ivar_getName(ivar)];
    [aCoder encodeObject:[self valueForKey:key] forKey:key];
  }
}

实现字典和模型的自动转换(MJExtension)

原理描述:用runtime提供的函数遍历Model自身所有属性,如果属性在json中有对应的值,则将其赋值。

核心方法:在NSObject的分类中添加方法


- (instancetype)initWithDict:(NSDictionary *)dict {

  if (self = [self init]) {
    //(1)获取类的属性及属性对应的类型
    NSMutableArray * keys = [NSMutableArray array];
    NSMutableArray * attributes = [NSMutableArray array];
    /*
     * 例子
     * name = value3 attribute = T@"NSString",C,N,V_value3
     * name = value4 attribute = T^i,N,V_value4
     */
    unsigned int outCount;
    objc_property_t * properties = class_copyPropertyList([self class], &outCount);
    for (int i = 0; i < outCount; i ++) {
      objc_property_t property = properties[i];
      //通过property_getName函数获得属性的名字
      NSString * propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
      [keys addObject:propertyName];
      //通过property_getAttributes函数可以获得属性的名字和@encode编码
      NSString * propertyAttribute = [NSString stringWithCString:property_getAttributes(property) encoding:NSUTF8StringEncoding];
      [attributes addObject:propertyAttribute];
    }
    //立即释放properties指向的内存
    free(properties);

    //(2)根据类型给属性赋值
    for (NSString * key in keys) {
      if ([dict valueForKey:key] == nil) continue;
      [self setValue:[dict valueForKey:key] forKey:key];
    }
  }
  return self;

}

以上就是Runtime应用的一些场景,本文到此结束了。