做项目时用到缓存用户自定义的对象,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);