首页 文章

iOS UserDefaults落后于已保存的内容

提问于
浏览
-1

这种情况有点过于复杂,仅用单词来描述,所以我创建了一个最小的演示项目供您下载和运行:

https://github.com/mattneub/DefaultsDemo

您将需要Xcode 10进行测试 . 这是项目运行时的样子:

enter image description here

项目代码似乎有相当多的不必要的混乱,但那是因为我已经包含了我的真实应用程序(纸牌游戏)中的最小材料来重现问题我的卡片和卡片布局,并且想法是当用户点击主页按钮时,我们收到应用程序将重新激活的通知,并且我们将卡组和卡布局保存到UserDefaults中 . 当我们重新启动时,我们检索卡组和卡布局,用户可以继续播放 .

但正如我将要解释的那样,它无法正常工作 . 而实际测试看到这种现象非常简单:

  • 在模拟器上运行项目 .

  • 点击随机播放按钮三到五次左右 . (如果你开始用完卡片,请点击New Deck按钮 . 但在我的测试中,这通常不是必需的 . )

  • 点击模拟器上的Home按钮 . 这导致我们保存到UserDefaults . 看看Xcode控制台;它告诉你有很多卡片在甲板上,只是保存在UserDefaults中 . 记住那个数字!

  • 返回Xcode,停止项目并再次运行,再次从步骤1开始 . 当我们启动时,您会被告知从UserDefaults中检索到的卡片中有多少张卡片 .

继续重复这四个步骤 . 我发生的事情是,在大约两到三个周期之后,步骤4中的数字与步骤3中的数字不同 . 我们不会从UserDefaults返回到我们刚刚保存到UserDefaults的同一套牌!

此外,我可以更多地说一下这个错误的数字:它是我们在某些早期保存到UserDefaults中的卡片中的卡片数量 . 就好像UserDefaults已经以某种方式无声地腐败并且已经停止接受新版本的套牌 .

为了说明,我刚刚清理了模拟器并打开了项目,我将运行它并告诉你我在控制台中看到的内容(评论解释我做了什么):

81 // launch
65
starting fresh 65
62 // shuffle
59 // shuffle
56 // shuffle
saving 56 // Home button

好的,让我们再次从Xcode启动:

retrieving 56 // launch
53 // shuffle
50 // shuffle
47 // shuffle
44 // shuffle
saving 44 // Home button

很好,让我们再次从Xcode发布:

retrieving 56 // launch

那个_778356落后了;我们正在从之前的保存中检索套牌,而不是我们刚刚保存的套牌 . (我实际上可以通过打印出甲板证明这一点;它有一个 description 属性就是为了这个目的,我实际上可以看到它是以前保存的套牌 . )

所以问题是:为什么?我知道如何解决它;保存到文件而不是UserDefaults . 但我在这里使用UserDefaults引起了这个问题 . 我怀疑其中一个对象是如何看到的,因为它们只是数据对象 .

(顺便说一句,调用 synchronize 什么都不做,在任何情况下都会根据 Headers 弃用,即使还没有正式批准 . )

1 回答

  • 0

    我要建议整个项目是一个红鲱鱼,问题是你的测试程序 .

    我认为 UserDefaults saves slowly :将UserDefaults更改为"take"只需要很长时间,即使在每个信号发生后发生了更改( synchronize 已经返回, didChange 通知已到达,依此类推) .

    因此,我只是没有在按下Home按钮和再次运行应用程序之间留出足够的时间 . 要看到这可能是这样,请进行以下更改:不要直接从步骤3转到步骤4,而是慢慢地插入步骤3a,数量为10 . 现在这个bug本身并没有表现出来 .

    (人们还可以争辩说,在 willResignActiveNotification 时间保存是错误的 . 保存的时间是相关数据发生变化的时候!因此,在测试示例中,我们应该在每次洗牌和交易操作结束时保存 - 而不是在用户点击主页按钮 . )

相关问题