• objective-c底层: runtime机制


    runtime是oc的真面目。oc底层的一套c语言API.

     unsigned int count;
        //获取属性列表
        objc_property_t *propertyList = class_copyPropertyList([self class], &count);
        for (unsigned int i=0; i<count; i++) {
            const char *propertyName = property_getName(propertyList[i]);
            NSLog(@"property---->%@", [NSString stringWithUTF8String:propertyName]);
        }
    
        //获取方法列表
        Method *methodList = class_copyMethodList([self class], &count);
        for (unsigned int i; i<count; i++) {
            Method method = methodList[i];
            NSLog(@"method---->%@", NSStringFromSelector(method_getName(method)));
        }
    
        //获取成员变量列表
        Ivar *ivarList = class_copyIvarList([self class], &count);
        for (unsigned int i; i<count; i++) {
            Ivar myIvar = ivarList[i];
            const char *ivarName = ivar_getName(myIvar);
            NSLog(@"Ivar---->%@", [NSString stringWithUTF8String:ivarName]);
        }
    
        //获取协议列表
        __unsafe_unretained Protocol **protocolList = class_copyProtocolList([self class], &count);
        for (unsigned int i; i<count; i++) {
            Protocol *myProtocal = protocolList[i];
            const char *protocolName = protocol_getName(myProtocal);
            NSLog(@"protocol---->%@", [NSString stringWithUTF8String:protocolName]);
        }

    应用1:KVC字典转模型

    Class clazz = Person.class;
    unsigned int count = 0;
    
    Person *person = [[Person alloc]init];
    NSDictionary *dict = @{@"name":@"zhangsan",@"age":@19, @"height": @1.75};
    
    Ivar *ivars = class_copyIvarList(clazz, &count);
    for (int i = 0; i < count; i++) {
        const char *cname = ivar_getName(ivars[i]);
        NSString *name = [NSString stringWithUTF8String:cname];
        NSString *key = [name substringFromIndex:1];
        
        const char *coding = ivar_getTypeEncoding(ivars[i]); // 获取类型
        NSString *strCode = [NSString stringWithUTF8String:coding];
        id value = dict[key];
        if ([strCode isEqualToString:@"f"]) {// 判断类型是否是float
            value = @(0.0);
        }
        
        [person setValue:value forKey:key];
    }
    NSLog(@"%@", person);

    应用2:NSCoding归档和解档

    - (void)encodeWithCoder:(NSCoder *)aCoder {
        unsigned int count = 0;
        Ivar *ivars = class_copyIvarList(self.class, &count);
        for (int i = 0; i < count; i++) {
            const char *cname = ivar_getName(ivars[i]);
            NSString *name = [NSString stringWithUTF8String:cname];
            NSString *key = [name substringFromIndex:1];
            
            id value = [self valueForKey:key]; // 取出key对应的value
            [aCoder encodeObject:value forKey:key]; // 编码
        }
    }
    - (id)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++) {
                const char *cname = ivar_getName(ivars[i]);
                NSString *name = [NSString stringWithUTF8String:cname];
                NSString *key = [name substringFromIndex:1];
                
                id value = [aDecoder decodeObjectForKey:key]; // 解码
                [self setValue:value forKey:key]; // 设置key对应的value
            }
        }
        return self;    
    }

    其他应用场景:

    交换方法实现,

    类对象的关联对象,

    动态添加方法,拦截未实现的方法

    动态创建一个类

  • 相关阅读:
    shell 脚本模板
    运动拉伸
    nature作图要求
    R语言画图曼哈顿图来源网络
    选择合适的统计图形和统计方法|图片来自松哥统计
    GO富集图
    batch gene expression plot
    植物生理生化研究进展
    手机图片
    jquery练习之超链接提示效果
  • 原文地址:https://www.cnblogs.com/wuxian/p/5971280.html
Copyright © 2020-2023  润新知