首页 > 技术文章 > Runtime

xiezefeng 2016-04-18 16:13 原文

1.runtime是一套底层的C语言API (很多包含强大的实用的C语言数据类型。C语言函数)

2.实际上,平时编写的OC代码,底层都是基于runtime实现的

也就是说,最终是转成底层runtime代码

    unsigned int count=0;
    Ivar * ivars= class_copyIvarList([UITextField class], &count);
   
    for (int i=0; i<count; i++) {
        Ivar ivar=*(ivars+i);
        NSLog(@"%s",ivar_getName(ivar));//访问所有的成员变量
    }

 

 

 

 

runtime 对象归档

//
//  car.m
//  rumtime对象归档
//
//  Created by 谢泽锋 on 16/4/18.
//  Copyright © 2016年 xiezefeng. All rights reserved.
//

#import "ObjectArchiving.h"
#import <objc/runtime.h>

@implementation ObjectArchiving
// 存档的时候需要实现
//- (void)encodeWithCoder:(NSCoder *)aCoder{
//    [aCoder encodeObject:self.name forKey:@"name"];
//    [aCoder encodeObject:self.sex forKey:@"sex"];
//}

// 解档的时候需要实现
//- (id)initWithCoder:(NSCoder *)aDecoder{
//    
//    if (self = [super init]) {
//        self.name = [aDecoder decodeObjectForKey:@"name"];
//        self.sex  = [aDecoder decodeObjectForKey:@"sex"];
//    }
//    return self;
//}

// 归档
- (void)encodeWithCoder:(NSCoder *)enCoder{
    // 取得所有成员变量名
    NSArray *properNames = [[self class] propertyOfSelf];
    
    for (NSString *propertyName in properNames) {
        // 创建指向get方法
        SEL getSel = NSSelectorFromString(propertyName);
        // 对每一个属性实现归档
        
        [enCoder encodeObject:[self performSelector:getSel] forKey:propertyName];
    }
}
// 返回self的所有对象名称
+ (NSArray *)propertyOfSelf{
//    OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount);

    unsigned int count;
    // 1. 获得类中的所有成员变量
    Ivar *ivarList = class_copyIvarList(self, &count);
    
    NSMutableArray *properNames =[NSMutableArray array];
    for (int i = 0; i < count; i++) {
        Ivar ivar = ivarList[i];
        
        // 2.获得成员属性名
        NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];
        
        // 3.除去下划线,从第一个角标开始截取
        NSString *key = [name substringFromIndex:1];
        
        [properNames addObject:key];
    }
    
    return [properNames copy];
}
// 解档
- (id)initWithCoder:(NSCoder *)aDecoder{
    // 取得所有成员变量名
    NSArray *properNames = [[self class] propertyOfSelf];
    NSLog(@"%@",properNames);
    for (NSString *propertyName in properNames) {
        // 创建指向属性的set方法
        // 1.获取属性名的第一个字符,变为大写字母
        NSString *firstCharater = [propertyName substringToIndex:1].uppercaseString;
        // 2.替换掉属性名的第一个字符为大写字符,并拼接出set方法的方法名
        NSString *setPropertyName = [NSString stringWithFormat:@"set%@%@:",firstCharater,[propertyName substringFromIndex:1]];
        SEL setSel = NSSelectorFromString(setPropertyName);
        [self performSelector:setSel withObject:[aDecoder decodeObjectForKey:propertyName]];
    }
    return  self;
}
//就这样,我们实现了对一个类实现自动归档的类,下次需要创建一个Model类时,只要继承自我们编写的这个类,就能实现自动归档啦,是不是很轻松呢。其实拿到类的属性名可以扩展很多内容,例如我们每次打印Model类的时候,都需要一个model里的属性都拼接出来,利用我们刚刚写的代码,重写description方法,就能实现在NSLog的时候把对象里的每个属性和值都打印出来了

- (NSString *)description{
    NSMutableString *descriptionString = [NSMutableString stringWithFormat:@"\n"];
    // 取得所有成员变量名
    NSArray *properNames = [[self class] propertyOfSelf];
    for (NSString *propertyName in properNames) {
        // 创建指向get方法
        SEL getSel = NSSelectorFromString(propertyName);
        
        NSString *propertyNameString = [NSString stringWithFormat:@"%@ - %@\n",propertyName,[self performSelector:getSel]];
        [descriptionString appendString:propertyNameString];
    }
    return [descriptionString copy];
}


@end

 

推荐阅读