对iOS中序列化的一些理解(写入文件)

这周要往程序中加入缓存,最后决定用序列化直接将对象存入文件充当缓存。

我使用的是archiveRootObject这个方法使用的序列化。

archiveRootObject可以将IOS常见的NSData,NSArray等写入文件,也可以将你自己定义的类型(必须实现了序列和凡序列化的,即遵循NSCoding协议,encodeWithCoder和initWithCoder:方法)写入文件。

这里我想创建了一个FileUtil的类来管理和得到文件的路径

#import 

@interface FileUtil : NSObject
+(NSString*)getDocumentPath;
+(NSString*)getDocumentFilePathWithFile:(NSString*)fileName dir:(NSString*)dir ,...NS_REQUIRES_NIL_TERMINATION;
@end
#import "FileUtil.h"

@implementation FileUtil

+(NSString*)getDocumentPath{
    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
}
//FIXME 这里dir没有使用,稍后检查
+(NSString*)getDocumentFilePathWithFile:(NSString*)fileName dir:(NSString*)dir ,...NS_REQUIRES_NIL_TERMINATION{
    NSString* path=[self getDocumentPath];
    id arg;
    va_list argList;
    if(dir)
    {
        va_start(argList,dir);
        while ((arg = va_arg(argList,id)))
        {
            path=[path stringByAppendingPathComponent:((NSString*)arg)];
        }
        va_end(argList);
    }
    [self createFileAtPath:path];
    path=[path stringByAppendingPathComponent:fileName];
    return path;
}
+(BOOL)createDocumentDirAtPath:(NSString*)dir,...NS_REQUIRES_NIL_TERMINATION{
    NSString* path=[self getDocumentPath];
    id arg;
    va_list argList;
    if(dir)
    {
        va_start(argList,dir);
        while ((arg = va_arg(argList,id)))
        {
            path=[path stringByAppendingPathComponent:((NSString*)arg)];
        }
        va_end(argList);
    }
    return [self createFileAtPath:path];
}
+(BOOL) createFileAtPath:(NSString*)path{
    NSFileManager* fm = [NSFileManager defaultManager];
    NSError * error=nil;
    if(![fm fileExistsAtPath:path]){
        [fm createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
    }
    if(error){
        log4debug(@"createDocumentDirAtPath Error !!!!---%@",[error localizedDescription]);
        return NO;
    }else{
        return YES;
    }

}
@end
一般情况下,要序列化的都是一个个的对象,把这些对象放到一个数组或者字典里存入文件。这里我要吧Condition这个对象存入数组。首先要将 Condition遵循NSCoding协议,实现encodeWithCoder和initWithCoder:方法
#import 

@interface Condition : NSObject
{
 
}
@property(retain,nonatomic)NSString *name;
@property(retain,nonatomic)UIImage *iconImage;
@property(retain,nonatomic)NSIndexPath *indexPathC;
@property(assign,nonatomic)BOOL isDefult;

@end

import "Condition.h"
#define NAME @"NAME"
#define ICON @"ICON"
#define ISDEFULT @"ISDEFULT"
#define INDEXPATH @"INDEXPATH"

@implementation Condition
@synthesize name;
@synthesize iconImage;
@synthesize isDefult;
@synthesize indexPathC;


-(id)initWithCoder:(NSCoder *)aDecoder{
    Condition* c =[self init];
    c.name = [aDecoder decodeObjectForKey:NAME];
    c.iconImage = [aDecoder decodeObjectForKey:ICON];
    c.isDefult = [aDecoder decodeBoolForKey:ISDEFULT];
    c.indexPathC = [aDecoder decodeObjectForKey:INDEXPATH];
  
    return  c;
}
-(void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:name forKey:NAME];
    [aCoder encodeObject:iconImage forKey:ICON];
    [aCoder encodeBool:isDefult forKey:ISDEFULT];
    [aCoder encodeObject:indexPathC forKey:INDEXPATH];
  
}

随后将元素都是一个个Condition对象的数组Conditions存入文件。(至于怎么将Condition对象加入数组就不必写了吧)
#define ARCHIVER_DIR @"archiver"
#define ARCHIVER_CONDITIONS @"archiver_conditions"
-(void)cacheConditions
{
   NSString* cacheFileName = @"test";
//archive conditions
        NSString* conditionsPath =[FileUtil getDocumentFilePathWithFile:cacheFileName dir:ARCHIVER_DIR,ARCHIVER_CONDITIONS ,nil];
 NSMutableArray * conditions;//存放一个个Condition对象的数组;
 [NSKeyedArchiver archiveRootObject:conditions toFile:conditionsPath];
}

读取文件中的内容(获取缓存)

-(void)uncacheConditions
{
    NSString* cacheFileName = @"test";

        NSString* conditionsPath =[FileUtil getDocumentFilePathWithFile:cacheFileName dir:ARCHIVER_DIR,ARCHIVER_CONDITIONS ,nil];
 NSMutableArray * conditions=[NSKeyedUnarchiver unarchiveObjectWithFile:conditionsPath];
}

另外,还有一种方法叫 writeToFile,可以将多个对象写入到同一个文件中。例如

NSMutableData *data = [NSMutableData data];

NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];

[archiver encodeObject:testArray1 forKey:@"testArray1"];

[archiver encodeObject:testArray2 forKey:@"testArray2"];

[archiver finishEncoding];

[data writeToFile:path atomically:YES];


你可能感兴趣的:(ios)