由于后台线程暂停延迟,在ApplicationDidEnterBackground中保存数据终止

时间:2014-06-06 02:53:53

标签: ios multithreading background nsmutablearray nscoder

我的应用目前从网络服务下载数据。接收的数据使用后台串行队列进行处理。

当用户进入后台模式并使用NSCoder执行此操作时,我还想将数据保存到文件系统。根据Apple的推荐,我将保存文件逻辑包含在app delegate的ApplicationDidEnterBackground方法中。

但是,我在调用保存到文件系统之前确保数据没有发生变化时遇到问题,因为后台线程暂停不会立即被调用。

例如,刷新客户端数据并返回2000+记录(简单数据方案)。但是,当它正在运行时,用户按下主页按钮,应用程序进入后台并尝试将数据保存到文件系统。

在后台线程的块处理中,我已经包含了在客户端添加到数组时记录的逻辑,以及包含NSLog消息以告诉我何时调用ApplicationDidEnterBackground方法。以下是记录结果的相关部分:

2014-06-06 12:32:02.360 MyApp[629:190049] Added client

2014-06-06 12:32:02.365 MyApp[629:190049] Added client

2014-06-06 12:32:02.416 MyApp[629:189936] This is a call to applicationDidEnterBackground to save data to file

2014-06-06 12:32:02.371 MyApp[629:190049] Added client

. . . (Log continues with Added Client messages)

2014-06-06 12:32:03.952 MyApp[629:190049] Added client

2014-06-06 12:32:03.951 MyApp[629:189936] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x157c74f0> was mutated while being enumerated.'

*** First throw call stack:

(0x23df543b 0x3096ed1f 0x23df4ec1 0x24ab44e7 0x24ab4ad9 0x24ab32ed 0x24affb53 0x4f879 0x4f71b 0x2a257 0x2762021d 0x2761c51d 0x2a32ae27 0x2a3319f5 0x23dbd135 0x23dbc3f9 0x23dbaf53 0x23d077e1 0x23d075f3 0x2ae5a261 0x27412e3d 0x27e4b 0x30f07aaf)

libc++abi.dylib: terminating with uncaught exception of type NSException

2014-06-06 12:32:03.960 MyApp[629:190049] Added client

2014-06-06 12:32:08.025 MyApp[629:190049] Added client

2014-06-06 12:32:08.028 MyApp[629:190049] Added client

2014-06-06 12:32:08.030 MyApp[629:190049] Added client

从日志中可以看出,即使在调用ApplicationDidEnterBackground之后(事实上,甚至在调用异常之后),后台线程块处理仍继续处理记录,从而导致文件保存由于变异数组而失败。

是否有人建议如何最好地处理以确保仅在后台队列暂停后才发生文件保存?如果可能的话,我宁愿不取消线程处理。提前谢谢。

1 个答案:

答案 0 :(得分:0)

如果其他人有类似的问题......

我通过将保存到文件方法添加到我处理每个数据集的相同后台队列而不是尝试取消部分方法来解决这个问题。

这样,在其他数据更新完成之前,保存数据没有启动,并且在阵列发生变异时保存到文件的问题已经消失。