NSUserDefault 存储自定义对象
NSUserDefault 只可以存储 int、bool 等基本数据类型,或者 NSString 、NSArray等 复合类型。但是,如果一个自定义的对象的话,那该怎样使用呢?
在 所写的类 中,需要实现两个协议:NSCoping、NSCoding。
这两个协议主要实现的方法是:
-
NSCoding
`- (instancetype)initWithCoder:(NSCoder *)aDecoder `- (void)encodeWithCoder:(NSCoder *)aCoder`
-
NSCoping
`- (id)copyWithZone:(NSZone *)zone
eg:
@interface Chinese ()<NSCoding, NSCopying>
@end
@implementation Chinese
`- (instancetype)initWithProvince:(NSString *)province height:(NSInteger)height isMale:(BOOL)isMale {
self = [super init];
if (self) {
_province = province;
_height = height;
_isMale = isMale;
}
return self;
}
`- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.province forKey:@"province"];
[aCoder encodeInteger:self.height forKey:@"height"];
[aCoder encodeBool:self.isMale forKey:@"isMale"];
}
\- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
self.province = [aDecoder decodeObjectForKey:@"province"];
self.height = [aDecoder decodeIntegerForKey:@"height"];
self.isMale = [aDecoder decodeBoolForKey:@"isMale"];
}
return self;
}
`- (id)copyWithZone:(NSZone *)zone {
Chinese *copyChinese = [[self class] allocWithZone:zone];
copyChinese.province = [self.province copyWithZone:zone];
copyChinese.isMale = self.isMale;
copyChinese.height = self.height;
return copyChinese;
}
类似这样的形式,自定义的一个类。
在使用上呢,则需要先对 该对象 进行 归档,即 archive。
eg:
Chinese *cantonese = [[Chinese alloc] initWithProvince:@"广东" height:180 isMale:YES];
NSData *chineseDate = [NSKeyedArchiver archivedDataWithRootObject:cantonese];
[[NSUserDefaults standardUserDefaults] setObject:chineseDate forKey:@"chinese"];
这是由于 本地化存储 的特性导致的。所以需要先归档成 NSData
类型,在对其进行存储。因此,在取出数据的时候,得到的是 NSData
数据类型,再对其进行解档 得到相对应的对象。eg:
NSData *chineseData = [[NSUserDefaults standardUserDefaults] objectForKey:@"chinese"];
Chinese *chinese = [NSKeyedUnarchiver unarchiveObjectWithData:chineseData];
基本流程,差不多就是这样。
那如果 自定义对象 的 一个属性 也是 自定义对象的话,比如:
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) Chinese *chinese;
@end
那么在实现 NSCoding
和 NSCoping
两个协议时,则
`- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.chinese = [aDecoder decodeObjectOfClass:[Chinese class] forKey:@"chinese"];
}
return self;
}
`- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.chinese forKey:@"chinese"];
}
`- (id)copyWithZone:(NSZone *)zone {
Person *copyPerson = [[self class] allocWithZone:zone];
copyPerson.name = [self.name copyWithZone:zone];
copyPerson.chinese = [self.chinese copyWithZone:zone];
return copyPerson;
}
小小拙见,有错请指出。谢谢!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。