1.类的头文件遵照<NSCoding>数组
@interface StudentModel : NSObject<NSCoding>
2.经过运行时,获取类中的全部成员属性,这里用到了运行时的方法spa
// Ivar:成员属性的意思 // 第一个参数:表示获取哪一个类中的成员属性 // 第二个参数:表示这个类有多少成员属性,传入一个Int变量地址,会自动给这个变量赋值 // 返回值Ivar *:指的是一个ivar数组,会把全部成员属性放在一个数组中,经过返回的数组就能所有获取到。 OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount)
因而咱们须要写一个方法,来返回一个数组类中的全部属性名称code
// 返回self的全部对象名称 + (NSArray *)propertyOfSelf{ 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]; }
3.在这里,咱们已经获取到类中的全部属性的名称,接着咱们须要在encodeWithCoder对属性名称和属性的值进行归档操做,在这里咱们遇到了一个问题,如何把属性名称和属性的值对应起来呢。orm
在这里咱们须要知道NSStringFromSelector(方法名)返回的是一个SEL变量指向方法名中的方法对象
咱们注意到每一个属性都有两个共同的方法那就是set方法和get方法,那么咱们只须要经过属性名字,建立属性名指向的方法也就是get方法,就能获取到属性名对应的值。继承
// 归档 - (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]; } }
4.接下来,咱们须要对类实现解档方法。这里咱们遇到第二个问题,如何对属性名的属性进行赋值呢?这里咱们须要用到属性的set方法,利用属性名,拼接出一个set方法的字符串,并建立一个指向属性set方法的SEL变量,而且利用performSelector实现赋值。ci
// 解档 - (id)initWithCoder:(NSCoder *)aDecoder{ // 取得全部成员变量名 NSArray *properNames = [[self class] propertyOfSelf]; 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类时,只要继承自咱们编写的这个类,就能实现自动归档啦。unicode