BTW, if you save on a background
thread, you also need to consider what
happens when your app is terminated
while a save operation is in progress.
Background threads get killed right
away, whereas the watchdog waits 5
seconds for the main thread to finish
up.
Now I’ve spent all day implementing NSOperation and creating NSManagedObjectContext instances directly inside the NSOperation subclasses so every NSOperation owns it’s own non-shared MOC. But now this is very bad news since a scenario like this, which likely happens all the time, would corrupt the Core Data database. I mean it can’t start to write a half byte of something in the sqlite3 file and then just stop right away.
And then there’s another problem: In my NSOperations I also do File I/O with NSFileManager.
So what can I do about this? Must I keep track of all running NSOperations and NSOperationQueues in my app und take care of them quickly in the App Delegate when the app gets terminated, so that I can tell the NSOperations to SFF (Save F*****g Fast) or cancel all operations, grab their MOC’s and “hard-save” them immediately? What’s best practice to solve this problem?
And why am I hearing about this the first time in my career? I mean none of the NSOperationQueue and Core Data mentioning books even talks about this but it seems it’s a random app killer that forces the user to re-install (and possibly lose tons of data) if we don’t take explicit care of this.
The main power of MOC is that represents an abstract storage that is independent from the format. It stores all it’s objects in the memory and uses the mechanism of transactions to commit any changes. So when you’re inserting/deleting/editing some objects that in MOC they are only changed in memory and not in persistent store (whether it is SQLite database, XML file or whatever). The changes are only committed when you call
save:method.As for NSOperation and file handling: if you want to stop some operation, you should call
cancelfor that. From docs:It means that if there is some IO operation running when you’re canceling an operation operation would wait until it is finished.
Also despite the Core Data transaction mechanism you should implement your own one for any data that is not managed by it (if needed).