0

我的应用程序当前从 Web 服务下载数据。接收到的数据使用后台串行队列进行处理。

当用户进入后台模式并使用 NSCoder 执行此操作时,我还想将数据保存到文件系统。根据 Apple 的建议,我在应用程序委托的 ApplicationDidEnterBackground 方法中包含了保存文件逻辑。

但是,在调用保存到文件系统之前,我无法确保数据不会发生变异,因为不会立即调用后台线程暂停。

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

在后台线程的块处理中,我已经包含了当客户端添加到数组时记录的逻辑,以及包含 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被调用后(事实上,甚至在异常被调用后)仍然继续处理记录,导致由于数组变异导致文件保存失败。

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

4

1 回答 1

0

万一其他人有类似的问题......

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

这样,在其他数据更新完成之前保存数据不会启动,并且在数组被变异时保存到文件的问题已经消失。

于 2014-06-18T23:26:22.623 回答