单例不会从应用程序委托持久化到另一个视图控制器中
点击此链接:如何使用 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]);
// ouput: Alphabet
然后,我分配/初始化一个 viewController 并将其设置为我的导航控制器的根视图控制器:
navController = [[UINavigationController alloc] initWithRootViewController:viewController];
在 viewController -> 中viewWillAppear,
我调用排序函数: [自我排序...];
在排序函数中,我调用单例类: Singleton *singleton = [Singleton共享Singleton];
但现在, NSLog(@"singleton sort: %@", [singleton sort]);
// output: amount NOT letter
我可以发布我的单例代码,但我知道它有效。事实上,在我的设置视图控制器中,如果我更改 [singleton sort] 变量,它将在所有视图控制器中持续存在。
这让我很困惑为什么我的单例对象不能从应用程序委托持久保存到我的视图控制器。任何提示/提示表示赞赏。
谢谢!!!
编辑:Singleton 类实现
在 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"];
}
Following this link: How do I archive two objects using NSKeyedArchiever? I am able to archieve an array and a singleton object. I can archieve and correctly unarchieve it at didFinishLaunchingWithOptions.
However, my singleton object does not persist past the app delegate. In the next view controller, the singleton variables goes back to its default value even though in didFinishLaunchingWithOptions, I did a NSLog and verified. Here is an example,
In application 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]);
// ouput: alphabet
Then, I alloc/init a viewController and set it as root view controller for my navigation controller:
navController = [[UINavigationController alloc] initWithRootViewController:viewController];
In viewController -> viewWillAppear,
I call a sorting function:
[self sort...];
And in the sorting function, I call the singleton class:
Singleton *singleton = [Singleton sharedSingleton];
But now, NSLog(@"singleton sort: %@", [singleton sort]);
// output: amount NOT alphabet
I can post my Singleton code but I know it works. In fact, in my settings view controller, if I change the [singleton sort] variable, it will persist through all view controllers.
This is confusing me as to why my singleton object does not persist from app delegate to my view controllers. Any tips/hints are appreciated.
Thanks!!!
EDIT: Singleton class implementation
In 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"];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在您的代码中,您只是更新当前上下文中的单例指针的值,而不是sharedSingleton实例
尝试在您的Singleton类中创建一个方法,该方法使用unarchiver对象更新单例类,例如:
或(我认为这是更好的)将代码移至 Singleton init 函数内。
In your code you are just updating the value of the singleton pointer in the current context and not the sharedSingleton instance
Try to create a method in your Singleton class which update the singleton class with the unarchiver object something like :
or (which is better I think) move your code inside the Singleton init function.
您还为局部变量分配了一个自动释放对象。该对象下次通过事件循环将超出范围(即释放)。
You've also assigned an autorelease object to a local variable. This object will become out of scope (i.e. released) next time through event loop.
我认为你弄错了单例模式。
中创建它,
您可以在代码
Singleton *singleton = [Singleton sharedSingleton];
这是正确的,但这样做
对于单例来说根本没有任何意义。一般来说,您不想从 nib 实例化您的单例。
I think you got the singleton pattern wrong.
You create it in code
Singleton *singleton = [Singleton sharedSingleton];
which is right, but doing
makes no sense for a singleton at all. Generally speaking, you do not want to instantiate your Singletons from nibs.
您的
singleton
指针只是一个局部变量,最初指向 Singleton 的共享实例。然后,您可以更改singleton
的值,以便它指向您从解档器中解码的对象。 使这个本地指针指向新的 Singleton 不会更改 Singleton 的共享实例,也不会更改shared
全局的值。此外,我认为您可能会误解单例模式。当不允许存在一个类的多个实例时,应该使用单例模式。单例经常被使用,因为它们很容易在全球范围内访问,但许多聪明人认为使用单例是对该模式的滥用。您可以同意或不同意这一点,但这里的事实是您正在创建 Singleton 类的两个实例,并且根据定义,这意味着您的 Singleton 类不是单例设计模式的真正实现。
Your
singleton
pointer is just a local variable that initially points to the shared instance of Singleton. You then come along and change the value ofsingleton
so that it points to the object that you decode from the unarchiver. Making this local pointer point to the new Singleton does not change the shared instance of Singleton, and it doesn't change the value of theshared
global either.Additionally, I think you might misunderstand the singleton pattern. The singleton pattern is supposed to be used when no more than one instance of a class can be allowed to exist. Singletons are often used because they're easy to access globally, but many smart people consider using singletons for this reason an abuse of the pattern. You can agree or disagree on this point, but the fact here is that you're creating two instances of your Singleton class, and by definition that means that your Singleton class is not a true implementation of the singleton design pattern.
下面给出的大多数注释都指向正确的方向,在我的原始代码中,我创建了 Singleton 类的两个实例。我意识到我的愚蠢,所以这里是有效的代码:
然后,使用 mySingleton 的唯一实例:
因此,这样,解档器会拉出一个自动释放的单例对象的实例,但该值设置为真正的 Singleton班级。
注意:一些评论提到我可能没有正确使用 Singleton 类,而且我可能没有正确使用。我不是这方面的专家。我只想保存一些内容并在应用程序终止时将其恢复。如果它对你有帮助,那就太好了。如果没有,请发表评论以帮助我们大家更好地学习。如果我变得更好并了解更多,也许我会更新这篇文章。
不过还是感谢所有的评论。他们都很好。我对他们所有人都投了赞成票。
Most of the comments given below points to the right direction in that in my original code, I was creating two instances of the Singleton class. And I realize my folly so here is the code that works:
Then, use the one and only instance of mySingleton:
So, this way, the unarchiver pulls an instance of a singleton object which is autoreleased but the value is set to the real Singleton class.
Note: some comments mentioned that I may not be using the Singleton class properly and I probably am not. I'm not expert at this. I just want to save something and have it back when the app terminates. If it helps you, great. If not, post a comment to help us all learn better. If I got better and learn more, maybe I'll update this post.
Thanks for all the comments though. They are all right. I've upvoted all of them.