I have a CoreData configuration where I stored measured data. The data is grouped by Session
, so each Session
entity has a one-to-many relationship with SensorData
. The Delete Rule is set to Cascade
. I also have a Delete All button. When it is pressed I run the following code.
// All sessions (cascading)
[self.context performBlockAndWait:^{
// Fetch only managedObjectID to reduce memory impact
NSFetchRequest *sessionsRequest = [NSFetchRequest fetchRequestWithEntityName:@"Session"];
[sessionsRequest setIncludesPropertyValues:NO];
NSError *sessionsError;
NSArray *allSessions = [self.context executeFetchRequest:sessionsRequest error:&sessionsError];
if (sessionsError) {
NSLog(@"Failed to fetch all sessions. %@", sessionsError);
}
// Release fetch request
sessionsRequest = nil;
// Loop and delete
int i = 0;
for (NSManagedObject *session in allSessions) {
NSLog(@"Deleting session (%d / %d)", ++i, allSessions.count);
if (i != allSessions.count) {
[self.context deleteObject:session];
}
}
NSLog(@"All session deleted.");
}];
NSLog(@"Saving.");
[self.context performBlock:^{
[self.document saveToURL:self.documentPath
forSaveOperation:UIDocumentSaveForOverwriting
completionHandler:^(BOOL success){
NSLog(@"Document saved %@.", success ? @"successfully" : @"unsuccessfully");
}];
}];
NSLog(@"Done saving.");
What happens is that I get the log output as below, so that executes fairly quickly. But the UI then freezes and RAM usage rockets. There are ~60 sessions and ~1M measurements (3 float values per measurement) and eventually RAM usage is too large and app crashes after 20 min or so, with all entries still there.
Obviously the saving is at play here, but what am I doing wrong? Grateful for any pointers.
Log output:
2015-08-13 15:16:56.825 MyApp[4201:1660697] Deleting session (1 / 61)
2015-08-13 15:16:56.826 MyApp[4201:1660697] Deleting session (2 / 61)
.
.
.
2015-08-13 15:16:56.862 MyApp[4201:1660697] Deleting session (60 / 61)
2015-08-13 15:16:56.863 MyApp[4201:1660697] Deleting session (61 / 61)
2015-08-13 15:16:56.863 MyApp[4201:1660697] All session deleted.
2015-08-13 15:16:56.864 MyApp[4201:1660697] Saving.
2015-08-13 15:16:56.864 MyApp[4201:1660697] Done saving.
Update
I edited the procedure to first delete the measurement data and by setting a fetch limit to keep RAM down (as suggested). However, if I delete 200 of SensorData
, saving takes around 3s, except for the first ~1000 entries. Deletion is fast though. See trace below.
I would like to fix this without deleting the document. Feels like a hack (albeit probably a good one).