Adding multi-threading to an application where data is shared between multiple threads (in this case, the data being created by the user and the data you are saving) is a difficult task to manage.
Instead of creating a thread or trying to save off all the data at once, put data to be saved into an internal "this must be saved off" list, and then work it off one N elements at a time periodically in your main thread.
If you get to the point where the user is leaving the screen or the app, then save off all the work that is left in the queue to the database immediately.
You can create a simple timed event (a few times per second) to do the work, which is a very simple approach.
- You can explicit control over how many items you save per update.
- You should never have concurrency issues.
- You should never have to worry about thread start/stop/termination
issues or mutexes.
To create it:
-(void)viewDidAppear:(BOOL)animated
{
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(saveData) userInfo:nil repeats:YES];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveAllRemainingItems) name:@"APP EXITING KEY" object:nil]
}
Your update function:
-(void)saveData
{
if([itemsToSave count] > 0)
{
....save off N items, remove from the list
}
}
-(void)saveAllRemainingItems
{
while([itemsToSave count] > 0)
{
...save first item.
[itemsToSave removeObjectAtIndex:0];
}
}
When you leave:
-(void)viewWillDisappear:(BOOL)animated
{
[self.timer invalidate];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self saveAllRemainingData];
}
To make sure you handle the "app is closing" situation, in your app delegate:
- (void)applicationWillTerminate:(UIApplication *)application
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"APP EXITING KEY" object:nil];
...OTHER CLEANUP ACTIVITIES
}