iOS中对于数据的存储通常使用sqlite或者coredata,也有部分使用文件存储的方式。iOS中的NSArray、NSString、NSDictionary、NSData等常规的数据对象都可以使用writeToFile:atomically:方法(注:这里NSArray中的对象必须是些iOS中的常规对象,如果是自定义的且有嵌套对象的,调用该方法会失败),因为实际操作中自定义对象的多样化,如果要实现文件保存通常要进行数据转换操作,然后再使用writeToFile:atomically:方法去写文件,读取的时候再按对象存储后的方式解析。为了实现通用性,本文使用<objc/runtime.h>中的方法对对象动态存储及解析。
以如下对象为例:
1、对象一嵌套ImageInfo对象
@interface HotRecommend : NSObject<NSCopying>
@property(nonatomic,retain) NSString *startTime;
@property(nonatomic,retain) NSString *endTime;
@property(nonatomic,retain) ImageInfo *img;
2、对象二嵌套CDCPoint对象
@interface ImageInfo : NSObject
@property (retain) NSString *Id;
@property (retain) NSString *Name;
@property (retain) NSString *Url;
@property (retain) NSNumber *Width;
@property (retain) NSNumber *Height;
@property (retain) NSString *SourceType;
@property(retain) CDCPoint *point;
3、对象三为常用数据类型
@interface CDCPoint : NSObject
@property(nonatomic,assign) float pointX;
@property(nonatomic,assign) float pointY;
方法如下(该方法可能未考虑到所有的对象转换情况,具体情况读者可以根据思路自行添加):
//对象转换为字典,调用该方法将自定义的对象转换为字典对象,(思路:通过遍历对象中的属性及其值进行转换)
+ (NSDictionary *)objToNSDictionary:(id)object
{
if ([object isKindOfClass:[NSDictionary class]]) {
return object;
}else{
NSMutableDictionary *dicRet = [[NSMutableDictionary alloc] initWithCapacity:0];
unsigned int count = 0;
objc_property_t *properties = class_copyPropertyList([object class], &count);
for( int i = 0; i < count; i++ )
{
objc_property_t property = properties[i];
const char *name = property_getName(property);
//获取对象属性名称及值
NSString *propertyName = [NSString stringWithUTF8String:name];
id value = [object valueForKey:propertyName];
if (value) {
if( ![value isKindOfClass:[NSArray class]]
&& ![value isKindOfClass:[NSString class]]
&& ![value isKindOfClass:[NSDictionary class]]
&& ![value isKindOfClass:[NSNumber class]])
{
NSDictionary *dicValue = [self objToNSDictionary:value];
[dicRet setObject:dicValue forKey:propertyName];
}else{
[dicRet setObject:value forKey:propertyName];
}
}else{
[dicRet setObject:@"" forKey:propertyName];
}
}
return dicRet;
}
}
//字典转化为制定名称的对象,className为你要转换成的对象名称,(请事先定义好类对象)
+(id)dicToObj:(NSDictionary *)dic withClassName:(NSString *)className;
{
Class clas = NSClassFromString(className);
id retObj = [[clas alloc] init];
unsigned int ivarsCnt = 0;
Ivar *ivars = class_copyIvarList(clas, &ivarsCnt);
for (const Ivar *p = ivars; p < ivars + ivarsCnt; ++p)
{
Ivar const ivar = *p;
// 获取变量名
NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
// 取得变量类型
const char *type = ivar_getTypeEncoding(ivar);
// 获取变量值
id value = [dic valueForKey:key];
NSString *str = [NSString stringWithUTF8String:type];
//获取嵌套自定义类名称
NSString *strTMp = [str stringByReplacingOccurrencesOfString:@"\"" withString:@""];
strTMp = [strTMp stringByReplacingOccurrencesOfString:@"@" withString:@""];
Class tmpClass = NSClassFromString(strTMp);
if (tmpClass != [NSString class] && tmpClass != [NSDictionary class] && tmpClass != [NSNumber class] && tmpClass != [NSArray class] && tmpClass != nil) {
id tmpValue = [self dicToObj:value withClassName:strTMp];
[retObj setValue:tmpValue forKey:key];
}else{
[retObj setValue:value forKey:key];
}
}
return retObj;
}