【问题标题】:NSUserDefaults will not load data consistentlyNSUserDefaults 不会一致地加载数据
【发布时间】:2013-09-08 16:31:47
【问题描述】:

我有一个基于标签的应用程序,并且希望每次在标签之间切换时重新加载数据。所以我使用了viewWillAppear:,它被调用但数据不会重新加载。这可能是使用大量[NSUserDefault] 的结果吗? 这是我的代码:

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [self reloadData];
}

-(void)reloadData {

    //Loading all the data
    totalApples = [[NSUserDefaults standardUserDefaults]integerForKey:@"totalApples"];
    [self setText:[NSString stringWithFormat:@"%.01f", totalApples] withExistingAttributesInLabel:self.applesLabel];

    applesPerSecond = [[NSUserDefaults standardUserDefaults]integerForKey:@"applesPerSecond"];
    [self setText:[NSString stringWithFormat:@"%.01f", applesPerSecond] withExistingAttributesInLabel:self.applesPerSecondLabel];

    applesPerClick = [[NSUserDefaults standardUserDefaults]integerForKey:@"applesPerClick"];
}

【问题讨论】:

  • ViewWillAppear,傻我
  • 哦,那有什么明显的问题吗? ;-)
  • 您能解释一下您所说的“但这仅在一半的时间里有效”是什么意思吗?
  • 有没有在 viewWillAppear 中设置断点并验证只调用了一半的时间?
  • 在将数据写入NSUserDefautls时,您是否调用synchronize

标签: ios objective-c nsuserdefaults


【解决方案1】:

使用NSUserDefaults 时,最好在写入数据后调用-synchronize

举个例子:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

[defaults setObject:@100 forKey:@"SomeKey"];

[defaults synchronize]; //This will ensure data is written.

如果您不调用此方法,系统会定期调用。但是,它可能会导致您可能遇到的时间问题。

阅读更多关于NSUserDefaults 和这种行为here 的信息。

更新

我认为这个问题现在正在失去它的背景。这是您在 cmets 下面发布的更新方法。可能值得发布一个后续问题,因为这可能不是 NSUserDefaults 的问题。

这里至少为后代提供了一个使用NSUserDefaults 写出数据的示例。由于正在执行乘法,我还更新了您的方法以将 priceFarmHands 保存为浮点数。 (它之前被写成整数,可能被截断了)。

- (void)buyFarmhand {
    farmHands++;
    totalApples -= priceFarmHands;

    if(priceFarmHands < 1000) {
        priceFarmHands = priceFarmHands * 1.35;
    } else if(priceFarmHands < 10000) {
        priceFarmHands = priceFarmHands * 1.25;
    } else {
        priceFarmHands = priceFarmHands * 1.15;
    }

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    [defaults setFloat:priceFarmHands forKey:@"priceFarmHands"];
    [defaults setInteger:farmHands forKey:@"farmHands"];
    [defaults setDouble:totalApples forKey:@"totalApples"];

    [defaults synchronize];

    [self setText:[NSString stringWithFormat:@"%.f", priceFarmHands] withExistingAttributesInLabel:self priceFarmHandsLabel];
    [self setText:[NSString stringWithFormat:@"%d", farmHands] withExistingAttributesInLabel:self.numberFarmhands];
}

【讨论】:

  • 您是否也必须这样做才能加载数据,因为我仍然遇到这种行为
  • 根据文档调用 synchronize '将对持久域的任何修改写入磁盘并将所有未修改的持久域更新到磁盘上的内容。所以在读取您的数据之前致电synchronize 可能会有所帮助。如果没有,那么您的数据可能不是每次都被写入,您应该确保设置数据的代码被调用并且没有 if 语句被跳过。
  • @SHERRICRANE 你能显示正在写入用户默认值的代码吗?就像不将值存储为 NSNumber 对象一样简单。
  • 另外我刚刚注意到您正在以整数形式检索数据,但试图格式化标签中的浮点数。检查数据类型。
  • 从一个选项卡到另一个选项卡都能完美运行,但另一方面它不会多次传递数据
【解决方案2】:

我看不到您在哪里创建 NSUserdefault 对象,它应该在 reloadData 方法中创建,这应该可以:

-(void)reloadData {
    //Loading all the data
    NSUserDefaults *appleData = [NSUserDefaults standardUserDefaults];
    totalApples = [appleData integerForKey:@"totalApples"];
    applesPerSecond = [appleData integerForKey:@"applesPerSecond"];
    applesPerClick = [integerForKey:@"applesPerClick"];

    //Set the labels text
    [self setText:[NSString stringWithFormat:@"%.01f", totalApples] 
                    withExistingAttributesInLabel:self.applesLabel];
    [self setText:[NSString stringWithFormat:@"%.01f", applesPerSecond] 
               withExistingAttributesInLabel:self.applesPerSecondLabel];
}

为了帮助您解决这个问题,添加一些日志到viewWillAppear:

-(void)viewWillAppear:(BOOL)animated{
    NSLog(@"viewWillAppear called, reloadind data...");
    [super viewWillAppear:animated];
    [self reloadData];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    • 2015-04-22
    • 1970-01-01
    • 2012-01-29
    • 1970-01-01
    相关资源
    最近更新 更多