ios 利用反射机制 封装 保存自定义数据模型的工具
oc本身是能进行数据存储的,只是他所提供的类只能存储系统自带的数据结构,然而实际中要保存的数据远远要复杂的多,如果再用NSUserDetails来保存就太麻烦了,费事费力还不好维护.
1.建两个属性类
#import <Foundation/Foundation.h>
@interface XMDataProperties : NSObject
@property (weak, nonatomic) NSString *name;
@property (weak, nonatomic) NSString *type;
@property (weak, nonatomic) NSString *value;
@end
#import "XMDataProperties.h"
@implementation XMDataProperties
@end
主体代码
#import <Foundation/Foundation.h>
#import "XMDataProperties.h"
@interface XMDataSavingTools : NSObject
+(void) save: (NSObject *) obj forKey:(NSString *) key;
+(id) load:(NSString *) key;
@end
#import "XMDataSavingTools.h"
#include <objc/runtime.h>
@implementation XMDataSavingTools
+(void) save:(id)obj forKey:(NSString *) key{
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSDictionary *keyLibrart = [userDefault objectForKey:@"keyLibrart"];
NSMutableDictionary *newKeyLibrart = [[NSMutableDictionary alloc] init];
if (keyLibrart == nil) {
keyLibrart = [[NSMutableDictionary alloc] init];
}
NSMutableArray *array = [[NSMutableArray alloc] init];
[self save:obj forKey:key array:array];
[newKeyLibrart setObject:array forKey:key];
[userDefault setObject:[newKeyLibrart copy] forKey:@"keyLibrart"];
NSLog(@"%ld",array.count);
[userDefault synchronize];
}
+(void) save:(id)obj forKey:(NSString *) key array :(NSMutableArray *)array{
NSString *str = NSStringFromClass([obj class]);
NSArray *list = [self getProperties:obj];
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSLog(@"%ld",list.count);
for (XMDataProperties *data in list) {
Class class = NSClassFromString([[data.type substringFromIndex:2] substringToIndex:data.type.length-3]);
if ([[NSDate class] isEqual:class] || [[NSString class] isEqual:class] || [[NSNumber class] isEqual:class] ||[[NSArray class] isEqual:class]
|| [[NSDictionary class] isEqual:class]) {
[array addObject:[NSString stringWithFormat:@"%@.%@.%@",key,str,data.name]];
[userDefault setObject:data.value forKey:[NSString stringWithFormat:@"%@.%@.%@",key,str,data.name]];
}else{
[self save:data.value forKey:[NSString stringWithFormat:@"%@.%@.%@",key,str,data.name] array:array];
}
}
}
+(id) load:(NSString *) key{
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *keyLibrart = [userDefault objectForKey:@"keyLibrart"];
NSMutableArray *array = [keyLibrart objectForKey:key];
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
id class = nil;
NSLog(@"%ld",array.count);
for (NSString *attr in array) {
NSArray *attrSp = [attr componentsSeparatedByString:@"."];
class = [NSClassFromString(attrSp[1]) alloc];
NSLog(@"%@",attr);
}
[self load:key assignment:class array:array index:0];
if (class == nil) {
return nil;
}else{
return class;
}
}
+(void) load:(NSString *) key assignment:(id) obj array:(NSMutableArray *) array index:(int) index{
index++;
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
unsigned int count;// 记录属性个数
Ivar *ivars = class_copyIvarList([obj class], &count);
for (int i = 0 ; i < count; i++) {
if (i >= array.count) {
continue;
}
NSArray *attrSp = [array[i] componentsSeparatedByString:@"."];
Ivar ivar = ivars[i];
if (attrSp.count >= (index+2)) {
object_setIvar(obj, ivar, [userDefaults objectForKey:array[i]]);
NSLog(@"%@",[userDefaults objectForKey:array[i]]);
}else if (attrSp.count >= (index+3)){
const char *memberType = ivar_getTypeEncoding(ivar);
NSString *type = [NSString stringWithFormat:@"%s",memberType];
Class class = NSClassFromString([[type substringFromIndex:2] substringToIndex:type.length-3]);
object_setIvar(obj, ivar, class);
[self load:key assignment:class array:array index:index];
}
}
}
//返回当前类的所有属性
+ (NSArray *)getProperties:(id)obj{
Class cls = [obj class];
// 获取当前类的所有属性
unsigned int count;// 记录属性个数
// 遍历
Ivar *ivars = class_copyIvarList(cls, &count);
NSMutableArray *map = [[NSMutableArray alloc] init];
for (int i = 0 ; i < count; i++) {
Ivar ivar = ivars[i];
const char *memberName = ivar_getName(ivar);
const char *memberType = ivar_getTypeEncoding(ivar);
id memberValue = object_getIvar(obj, ivar);
XMDataProperties *data = [[XMDataProperties alloc] init];
data.name = [NSString stringWithFormat:@"%s",memberName];
data.type = [NSString stringWithFormat:@"%s",memberType];
data.value = memberValue;
[map addObject:data];
}
return map.copy;
}
@end