Singleton不会从app delegate持久存储到另一个视图控制器中

时间:2011-06-29 15:35:43

标签: iphone singleton nskeyedarchiver

点击此链接: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"];
}

5 个答案:

答案 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类,我可能不是。我不是这方面的专家。我只想保存一些内容,并在应用程序终止时将其恢复。如果它对你有帮助,那很好。如果没有,发表评论以帮助我们更好地学习。如果我变得更好并且了解更多,也许我会更新这篇文章。

感谢所有评论。他们没事。我赞成所有这些。