My app currently downloads data from a web service. The data received is processed using background serial queues.
I also want to save the data to the file system when the user goes into background mode and use NSCoder to do this. Based on Apple's recommendation, I have included the save file logic in the ApplicationDidEnterBackground method of the app delegate.
However, I am having problems ensuring the data is not mutated before the save to file system is called because the background thread pause is not called immediately.
For example, a refresh of client data is kicked off and returns 2000+ records (simple data scheme). However, while this is running, the user presses the Home button and the App goes into the background and attempts to save the data to file system.
Within the block processing of the background thread, I have included logic to log when clients are added to the array, as well as included NSLog messages to tell me when the ApplicationDidEnterBackground method is called. Here are the relevant parts of the logging results:
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
As can be seen from the logs, the background thread block processing continues to process records even after ApplicationDidEnterBackground is called (and in fact, even after the exception is called), causing the file save to fail due to a mutated array.
Does anyone have any suggestions on how best to handle ensuring the save of file only occurs AFTER the background queue is paused? I would prefer not to cancel the thread processing if possible. Thanks in advance.