我一直在努力教自己如何使用NSCoder的存档/取消归档方法,但我很难过。
我有一个我用8个NSInteger属性定义的Singleton类。我试图将此对象保存到磁盘,然后根据需要从磁盘加载。
我已经将保存部分关闭了,我也将负载部分关闭(根据NSLogs),但在我的“initWithCoder:”方法适当地加载对象的属性后,“init”方法运行并重置我的对象的属性回归零。
我可能在这里遗漏了一些基本的东西,但感谢任何帮助!
我对Singleton类的类方法:
+ (Actor *)shareActorState
{
static Actor *actorState;
@synchronized(self) {
if (!actorState) {
actorState = [[Actor alloc] init];
}
}
return actorState;
}
-(id)init
{
if (self = [super init]) {
NSLog(@"New Init for Actor started...\nStrength: %d", self.strength);
}
return self;
}
-(id)initWithCoder:(NSCoder *)coder
{
if (self = [super init]) {
strength = [coder decodeIntegerForKey:@"strength"];
dexterity = [coder decodeIntegerForKey:@"dexterity"];
stamina = [coder decodeIntegerForKey:@"stamina"];
will = [coder decodeIntegerForKey:@"will"];
intelligence = [coder decodeIntegerForKey:@"intelligence"];
agility = [coder decodeIntegerForKey:@"agility"];
aura = [coder decodeIntegerForKey:@"aura"];
eyesight = [coder decodeIntegerForKey:@"eyesight"];
NSLog(@"InitWithCoder executed....\nStrength: %d\nDexterity: %d", self.strength, self.dexterity);
[self retain];
}
return self;
}
-(void) encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeInteger:strength forKey:@"strength"];
[encoder encodeInteger:dexterity forKey:@"dexterity"];
[encoder encodeInteger:stamina forKey:@"stamina"];
[encoder encodeInteger:will forKey:@"will"];
[encoder encodeInteger:intelligence forKey:@"intelligence"];
[encoder encodeInteger:agility forKey:@"agility"];
[encoder encodeInteger:aura forKey:@"aura"];
[encoder encodeInteger:eyesight forKey:@"eyesight"];
NSLog(@"encodeWithCoder executed....");
}
-(void)dealloc
{
//My dealloc stuff goes here
[super dealloc];
}
当谈到这些东西并且上个月一直在努力教我自己时,我是一个菜鸟,所以原谅任何明显的事情。
感谢您的帮助!
答案 0 :(得分:2)
我一直使用以下模板,并发现它非常有用。单例状态的加载和保存是封装的,您所要做的就是要求共享实例。您可能希望公开persistToStorage
并从应用委托的applicationWillTerminate:
方法中调用它。
(您可能希望使此线程更安全。)
static Actor* SharedActor;
+(Actor*)sharedActor
{
if (SharedActor)
return SharedActor;
SharedActor = [[NSKeyedUnarchiver unarchiveObjectWithFile:[self actorDataFileName]]retain];
if (!SharedActor)
SharedActor = [[Actor alloc]init];
return SharedActor;
}
+(NSString*)actorDataFileName
{
NSString* path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
return [path stringByAppendingPathComponent:@"actor.dat"];
}
-(BOOL)persistToStorage
{
return [NSKeyedArchiver archiveRootObject:self toFile:[Actor userDataFileName]];
}
-(void) encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeInteger:strength forKey:@"strength"];
. . .
}
-(id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init])
{
strength = [decoder decodeIntegerForKey:@"strength"];
. . .
}
}
有几件事:
[self retain];
答案 1 :(得分:1)
我不确定有一个归档/取消归档的单例类是否合理。执行Actor *actor = [Actor shareActorState];
时,您正在访问共享实例。如果您然后归档NSData *data = [NSKeyedArchiver archivedDataWithRootObject:actor]
,那么您将保存正确的内容。
但是,当您取消归档时,您打算做什么? Actor *newactor = [NSKeyedUnarchiver unarchiveObjectWithData:data];
创建了一个新角色。它位于共享演员的新内存区域。此newactor
与单身[Actor shareActorState]
不同,并且违反了设计模式,因为您现在拥有多个对象。
更有可能的是,您希望在Actor
类上实现两个实例方法。他们将是:
- (NSData *)archiveStateToData;
- (void)unarchiveStateFromData:(NSData *)data;
实际上会更新实例中的值(使用归档)。如果您正在尝试学习NSCoding
协议以及如何归档/取消归档数据,我建议不要使用单例进行。
答案 2 :(得分:0)
虽然我同意@wbyoung你可能不应该归档/取消归档一个单身人士(除非你要经历NSUserDefaults),如果你这样做我相信它会起作用只是改变
-(id)initWithCoder:(NSCoder *)coder
{
if (self = [super init]) {
到
-(id)initWithCoder:(NSCoder *)coder
{
if (self = [self shareActorState]) {
(哦,我会将shareActorState重命名为sharedActorState,或者更好的是sharedActor)