简体   繁体   English

Singleton 不会从应用程序委托持续到另一个视图 controller

[英]Singleton does not persist from app delegate into another view controller

Following this link: How do I archive two objects using NSKeyedArchiever?按照此链接: 如何使用 NSKeyedArchiever 归档两个对象? I am able to archieve an array and a singleton object.我能够归档一个数组和一个 singleton object。 I can archieve and correctly unarchieve it at didFinishLaunchingWithOptions.我可以在 didFinishLaunchingWithOptions 中归档和正确取消归档它。

However, my singleton object does not persist past the app delegate.但是,我的 singleton object 不会持续通过应用程序委托。 In the next view controller, the singleton variables goes back to its default value even though in didFinishLaunchingWithOptions, I did a NSLog and verified.在下一个视图 controller 中,singleton 变量恢复到其默认值,即使在 didFinishLaunchingWithOptions 中,我做了一个 NSLog 并进行了验证。 Here is an example,这是一个例子,

In application didFinishLaunchingWithOptions :在应用程序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:然后,我分配/初始化一个 viewController 并将其设置为根视图 controller 用于我的导航 controller:

navController = [[UINavigationController alloc] initWithRootViewController:viewController];

In viewController -> viewWillAppear,在 viewController -> viewWillAppear 中,

I call a sorting function: [self sort...];我称之为排序 function: [self sort...];

And in the sorting function, I call the singleton class: Singleton *singleton = [Singleton sharedSingleton]; And in the sorting function, I call the singleton class: Singleton *singleton = [Singleton sharedSingleton]; But now, NSLog(@"singleton sort: %@", [singleton sort]);但是现在, NSLog(@"singleton sort: %@", [singleton sort]); // output: amount NOT alphabet // output:数量不是字母

I can post my Singleton code but I know it works.我可以发布我的 Singleton 代码,但我知道它有效。 In fact, in my settings view controller, if I change the [singleton sort] variable, it will persist through all view controllers.事实上,在我的设置视图 controller 中,如果我更改 [singleton sort] 变量,它将在所有视图控制器中持续存在。

This is confusing me as to why my singleton object does not persist from app delegate to my view controllers.这让我很困惑,为什么我的 singleton object 不会从应用程序委托持续到我的视图控制器。 Any tips/hints are appreciated.任何提示/提示表示赞赏。

Thanks!!!谢谢!!!

EDIT: Singleton class implementation编辑:Singleton class 实现

In Singleton.m:在 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"];
}

In your code you are just updating the value of the singleton pointer in the current context and not the sharedSingleton instance在您的代码中,您只是在当前上下文中更新 singleton 指针的值,而不是 sharedSingleton 实例

Try to create a method in your Singleton class which update the singleton class with the unarchiver object something like: Try to create a method in your Singleton class which update the singleton class with the unarchiver object something like:

[[Singleton sharedSingleton] loadArchive:unarchiver];

or (which is better I think) move your code inside the Singleton init function.或者(我认为这更好)将您的代码移动到 Singleton init function 中。

You've also assigned an autorelease object to a local variable.您还将自动释放 object 分配给局部变量。 This object will become out of scope (ie released) next time through event loop.这个 object 将在下次通过事件循环时脱离 scope(即释放)。

singleton = [unarchiver decodeObjectForKey:@"singleton"];

I think you got the singleton pattern wrong.我认为您的 singleton 模式错误。

You create it in code您在代码中创建它

Singleton *singleton = [Singleton sharedSingleton];

which is right, but doing这是正确的,但是做

singleton = [unarchiver decodeObjectForKey:@"singleton"];

makes no sense for a singleton at all.对于 singleton 根本没有意义。 Generally speaking, you do not want to instantiate your Singletons from nibs.一般来说,您不想从 nib 实例化您的单例。

Your singleton pointer is just a local variable that initially points to the shared instance of Singleton.您的singleton指针只是一个局部变量,最初指向 Singleton 的共享实例。 You then come along and change the value of singleton so that it points to the object that you decode from the unarchiver.然后,您来更改singleton的值,使其指向您从解压缩器解码的 object。 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 the shared global either.使这个本地指针指向新的 Singleton 不会更改 Singleton 的共享实例,也不会更改shared全局的值。

Additionally, I think you might misunderstand the singleton pattern.此外,我认为您可能会误解 singleton 模式。 The singleton pattern is supposed to be used when no more than one instance of a class can be allowed to exist.当 class 的实例不超过一个时,应该使用 singleton 模式。 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. 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.

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.下面给出的大多数评论都指向正确的方向,在我的原始代码中,我正在创建 Singleton class 的两个实例。 And I realize my folly so here is the code that works:我意识到我的愚蠢,所以这里是有效的代码:

Singleton *singleton = [unarchiver decodeObjectForKey:@"singleton"];

Then, use the one and only instance of mySingleton:然后,使用 mySingleton 的唯一实例:

Singleton *mySingleton = [Singleton sharedSingleton];
[mySingleton setSort:[singleton sort]];

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. 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.注意:一些评论提到我可能没有正确使用 Singleton class,我可能没有。 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.我对他们都投了赞成票。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM