点击此链接:How do I archive two objects using NSKeyedArchiever?我能够建立一个数组和一个单例对象。我可以在didFinishLaunchingWithOptions上实现并正确地解除它。
但是,我的单例对象不会超过应用程序委托。在下一个视图控制器中,单例变量返回到其默认值,即使在didFinishLaunchingWithOptions中,我做了一个NSLog并进行了验证。这是一个例子,
在申请didFinishLaunchingWithOptions
中:
Singleton *singleton = [Singleton sharedSingleton];
NSData *data = [NSData dataWithContentsOfFile:path];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
singleton = [unarchiver decodeObjectForKey:@"singleton"];
[unarchiver finishDecoding];
NSLog(@"singleton sorting after decode: %@", [singleton sort]);
//输出:字母
然后,我分配/初始化一个viewController并将其设置为导航控制器的根视图控制器:
navController = [[UINavigationController alloc] initWithRootViewController:viewController];
在viewController中 - > viewWillAppear中,
我称之为排序功能: [self sort ...];
在排序函数中,我调用单例类:
单身*singleton = [Singleton sharedSingleton];
但是现在,NSLog(@"singleton sort: %@", [singleton sort]);
//输出:金额不是字母
我可以发布我的Singleton代码,但我知道它有效。实际上,在我的设置视图控制器中,如果我更改[singleton sort]变量,它将在所有视图控制器中保持不变。
这让我很困惑,为什么我的单例对象不会从app委托持久保存到我的视图控制器。任何提示/提示都表示赞赏。
感谢!!!
编辑:单例类实现
在Singleton.m中:
static Singleton *shared = NULL;
+ (id)sharedSingleton
{
@synchronized(self)
{
if ( !shared || shared == NULL )
{
// allocate the shared instance, because it hasn't been done yet
NSLog(@"Allocating Singleton...");
shared = [[Singleton alloc] init];
}
return shared;
}
}
- (id)init
{
if ( self = [super init] )
{
sort = [[NSString alloc] initWithString:@"amount"];
showTutorial = YES;
}
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
[super init];
[self setSort:[aDecoder decodeObjectForKey:@"sort"]];
[self setShowTutorial:[aDecoder decodeBoolForKey:@"showTutorial"]];
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:sort forKey:@"sort"];
[aCoder encodeBool:showTutorial forKey:@"showTutorial"];
}
答案 0 :(得分:2)
在您的代码中,您只是更新当前上下文中单例指针的值而不是sharedSingleton实例
尝试在Singleton类中创建一个方法,该方法使用unarchiver对象更新单例类:
[[Singleton sharedSingleton] loadArchive:unarchiver];
或(我认为这更好)在Singleton init函数中移动代码。
答案 1 :(得分:2)
您还为本地变量分配了一个autorelease对象。下次通过事件循环时,此对象将超出范围(即已释放)。
singleton = [unarchiver decodeObjectForKey:@"singleton"];
答案 2 :(得分:2)
我认为你的单身模式错了。
您可以在代码
中创建它 Singleton *singleton = [Singleton sharedSingleton];
这是对的,但正在做
singleton = [unarchiver decodeObjectForKey:@"singleton"];
对单身人士毫无意义。一般来说,你不想从笔尖实例化你的单身人士。
答案 3 :(得分:1)
您的singleton
指针只是一个局部变量,最初指向Singleton的共享实例。然后,您可以更改singleton
的值,使其指向您从unarchiver解码的对象。 使此本地指针指向新的Singleton不会更改Singleton的共享实例,也不会更改shared
全局的值。
另外,我认为你可能会误解单身模式。当允许存在不超过一个类的实例时,应该使用单例模式。单身人士经常被使用,因为他们很容易在全球范围内访问,但许多聪明的人因为这个原因而考虑使用单身人士滥用这种模式。你可以同意或不同意这一点,但这里的事实是你正在创建Singleton类的两个实例,并且根据定义,这意味着你的Singleton类不是单例设计模式的真正实现。
答案 4 :(得分:0)
下面给出的大多数评论指出了正确的方向,在我的原始代码中,我创建了Singleton类的两个实例。我意识到我的愚蠢,所以这里的代码是有效的:
Singleton *singleton = [unarchiver decodeObjectForKey:@"singleton"];
然后,使用mySingleton的唯一实例:
Singleton *mySingleton = [Singleton sharedSingleton];
[mySingleton setSort:[singleton sort]];
因此,这样,unarchiver会拉出一个自动释放的单例对象的实例,但该值设置为真正的Singleton类。
注意:有些评论提到我可能没有正确使用Singleton类,我可能不是。我不是这方面的专家。我只想保存一些内容,并在应用程序终止时将其恢复。如果它对你有帮助,那很好。如果没有,发表评论以帮助我们更好地学习。如果我变得更好并且了解更多,也许我会更新这篇文章。
感谢所有评论。他们没事。我赞成所有这些。