第六十三篇runtime实现归解档
Posted 久冬不雨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第六十三篇runtime实现归解档相关的知识,希望对你有一定的参考价值。
#import <objc/runtime.h> #import <objc/message.h> @implementation HDFArchiveModel - (void)encodeWithCoder:(NSCoder *)aCoder { unsigned int outCount = 0; Ivar *ivars = class_copyIvarList([self class], &outCount); for (unsigned int i = 0; i < outCount; ++i) { Ivar ivar = ivars[i]; // 获取成员变量名 const void *name = ivar_getName(ivar); NSString *ivarName = [NSString stringWithUTF8String:name]; // 去掉成员变量的下划线 ivarName = [ivarName substringFromIndex:1]; // 获取getter方法 SEL getter = NSSelectorFromString(ivarName); if ([self respondsToSelector:getter]) { const void *typeEncoding = ivar_getTypeEncoding(ivar); NSString *type = [NSString stringWithUTF8String:typeEncoding]; // const void * if ([type isEqualToString:@"r^v"]) { const char *value = ((const void *(*)(id, SEL))(void *)objc_msgSend)((id)self, getter); NSString *utf8Value = [NSString stringWithUTF8String:value]; [aCoder encodeObject:utf8Value forKey:ivarName]; continue; } // int else if ([type isEqualToString:@"i"]) { int value = ((int (*)(id, SEL))(void *)objc_msgSend)((id)self, getter); [aCoder encodeObject:@(value) forKey:ivarName]; continue; } // float else if ([type isEqualToString:@"f"]) { float value = ((float (*)(id, SEL))(void *)objc_msgSend)((id)self, getter); [aCoder encodeObject:@(value) forKey:ivarName]; continue; } id value = ((id (*)(id, SEL))(void *)objc_msgSend)((id)self, getter); if (value != nil && [value respondsToSelector:@selector(encodeWithCoder:)]) { [aCoder encodeObject:value forKey:ivarName]; } } } free(ivars); } - (instancetype)initWithCoder:(NSCoder *)aDecoder { if (self = [super init]) { unsigned int outCount = 0; Ivar *ivars = class_copyIvarList([self class], &outCount); for (unsigned int i = 0; i < outCount; ++i) { Ivar ivar = ivars[i]; // 获取成员变量名 const void *name = ivar_getName(ivar); NSString *ivarName = [NSString stringWithUTF8String:name]; // 去掉成员变量的下划线 ivarName = [ivarName substringFromIndex:1]; // 生成setter格式 NSString *setterName = ivarName; // 那么一定是字母开头 if (![setterName hasPrefix:@"_"]) { NSString *firstLetter = [NSString stringWithFormat:@"%c", [setterName characterAtIndex:0]]; setterName = [setterName substringFromIndex:1]; setterName = [NSString stringWithFormat:@"%@%@", firstLetter.uppercaseString, setterName]; } setterName = [NSString stringWithFormat:@"set%@:", setterName]; // 获取getter方法 SEL setter = NSSelectorFromString(setterName); if ([self respondsToSelector:setter]) { // 获取数据的类型 const void *typeEncoding = ivar_getTypeEncoding(ivar); NSString *type = [NSString stringWithUTF8String:typeEncoding]; NSLog(@"%@", type); // const void * if ([type isEqualToString:@"r^v"]) { NSString *value = [aDecoder decodeObjectForKey:ivarName]; if (value) { ((void (*)(id, SEL, const void *))objc_msgSend)(self, setter, value.UTF8String); } continue; } // int else if ([type isEqualToString:@"i"]) { NSNumber *value = [aDecoder decodeObjectForKey:ivarName]; if (value != nil) { ((void (*)(id, SEL, int))objc_msgSend)(self, setter, [value intValue]); } continue; } else if ([type isEqualToString:@"f"]) { NSNumber *value = [aDecoder decodeObjectForKey:ivarName]; if (value != nil) { ((void (*)(id, SEL, float))objc_msgSend)(self, setter, [value floatValue]); } continue; } // object id value = [aDecoder decodeObjectForKey:ivarName]; if (value != nil) { ((void (*)(id, SEL, id))objc_msgSend)(self, setter, value); } } } free(ivars); } return self; } + (void)test { HDFArchiveModel *archiveModel = [[HDFArchiveModel alloc] init]; archiveModel.archive = @"自动归档"; archiveModel.session = "http://www.henishuo.com"; archiveModel.totalCount = @(123); archiveModel.referenceCount = 10; archiveModel._floatValue = 10.0; NSString *path = NSHomeDirectory(); path = [NSString stringWithFormat:@"%@/archive", path]; [NSKeyedArchiver archiveRootObject:archiveModel toFile:path]; HDFArchiveModel *unarchiveModel = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; } @end
以上是关于第六十三篇runtime实现归解档的主要内容,如果未能解决你的问题,请参考以下文章