做项目时用到缓存用户自定义的对象,NSUserDefaults不能用,所以就看了下NSCoding协议,发现比较好用:

如自定义类:

@interface CarStyle : NSObject<NSCoding> {  // 使用NSConding协议,引入协议
    NSString *carStyle;
}

@property (nonatomic, retain)     NSString *carStyle;

@end


实现类:CarStyle

#import "CarStyle.h"

@implementation CarStyle
@synthesize carStyle;

- (id)init{
    if (self = [super init]) {
        self.carStyle = @"hello";
    }
    
    return  self;
}
   
- (void)dealloc {
    [carStyle release];
    
    [super dealloc];
}
// 协议方法
- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:carStyle forKey:@"carStyle"];
}
// 反序列化时提取成员变量
- (id)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super init]) {
        self.carStyle = [aDecoder decodeObjectForKey:@"carStyle"];

    }
    return  self;
}

@end

实现类:CarSeries

@interface CarSeries : NSObject<NSCoding> {
    NSString *carType;
    NSMutableArray *carStyleArray;
}

@property (nonatomic, retain) NSString *carType;
@property (nonatomic, retain) NSMutableArray *carStyleArray;

@end


#import "CarSeries.h"
#import "CarStyle.h"

@implementation CarSeries
@synthesize carType, carName,carStyleArray;

- (id)init {
    if (self = [super init]) {
        self.carName = @"BENCHI";
        self.carType = @"also BENCHI";
        NSMutableArray *muArray = [[NSMutableArray alloc] init];
        self.carStyleArray = muArray;
        [muArray release];
    }
    
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:carType forKey:@"carType"];

   // 如果这个可变数组含有其他自定义的对象时,不能直接这样:

  // [aCoder encodeObject:carStyleArray forKey:@"carStyleArray"];
    
   // 需要手动重新对他使用NSCoding进行转换
    for (int i = 0; i < [carStyleArray count]; ++i) {
        NSString *fileName = [NSString stringWithFormat:@"tmp/carStyle%d.carStyle", i];
        NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:fileName];
        
        CarStyle *_carStyle = [carStyleArray objectAtIndex:i];
        NSData *freezeData = [NSKeyedArchiver archivedDataWithRootObject:_carStyle];
        [freezeData writeToFile:path atomically:YES];
    }
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super init]) {
        self.carType = [aDecoder decodeObjectForKey:@"carType"];
       

       // 检索出保存的自定义对象的文件,此处保存成多个文件,待修改成更好的方法
        NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp"];
        NSArray *filterArray = [NSArray arrayWithObjects:@"carStyle", nil];
        NSArray *fileArray = [[[NSFileManager defaultManager] subpathsOfDirectoryAtPath:path error:nil] pathsMatchingExtensions:filterArray];
       

       self.carStyleArray = [NSMutableArray array];  // 注意在这里重新初始化数组否则无法使用
        for (int i = 0; i < [fileArray count]; ++i) {
            NSString *filePath = [NSString stringWithFormat:@"%@/%@", path, [fileArray objectAtIndex:i]];
            NSData *fileData = [NSData dataWithContentsOfFile:filePath];
            CarStyle *_carStyle = [NSKeyedUnarchiver unarchiveObjectWithData:fileData];
            
            [self.carStyleArray addObject:_carStyle];
        }
        // 也不能简单的这样取得carStyleArray的值
        //self.carStyleArray = [aDecoder decodeObjectForKey:@"carStyleArray"];
    }
    return  self;
}
- (void)dealloc {
    [carType release];
    [carStyleArray release];
    
    [super dealloc];
}

@end


使用:

CarStyle *carStyle = [[CarStyle alloc] init];
CarSeries *carSeries = [[CarSeries alloc] init];
[carSeries.carStyleArray addObject:carStyle];
NSLog(@"%@", carSeries);
// 取出保存的对象
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp/carType.txt"];
NSData *freezeDird = [NSKeyedArchiver archivedDataWithRootObject:carSeries];

[freezeDird writeToFile:path atomically:YES];

CarSeries *aCarseries;
NSData *fileData;
fileData = [NSData dataWithContentsOfFile:path];
aCarseries = [NSKeyedUnarchiver unarchiveObjectWithData:fileData];
   
NSLog(@"carType=%@, carName=%@, carArray=%@", aCarseries.carType, aCarseries.carName, aCarseries.carStyleArray);