• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

objective-c底层:runtime机制

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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;    
}

其他应用场景:

交换方法实现,

类\对象的关联对象,

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

动态创建一个类


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Objective-C中的@property和@synthesize用法发布时间:2022-07-12
下一篇:
建立iOS专属文档之Objective-C API文档生成器发布时间:2022-07-12
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap