I run my program that creates Core Data content that is displayed in a NSOutlineView using NSTreeController. The second time I run my program I want to clean the content of my NSTreeController
and I run the method pasted below. The method either hangs for a long time (600 seconds) before it finishes or it crashes. If I have few entities (500-1000) in my NStreeController
it takes much less time compared to if I have a lot (200,000) entities to pass this method, if it passes at all. What I need to know is if there is a better way to clear/refresh/reset the content of my NStreeController
to clear my NSoutlineView
before I re-run my program and fill up the NStreeController
again. Specifically, I would like my NSOutlineView
to respond quickly to changes to the contents of my NSTreeController
, and I need the content of my Core Data driven NSTreeController
to be able to be reset.
-(void) cleanSDRDFileObjects
{
__weak __typeof__(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf.outlineView collapseItem:nil collapseChildren:YES];
[weakSelf.coreDataController._coreDataHelper.context performBlockAndWait:^{
NSEntityDescription *entityDescription = [NSEntityDescription
entityForName:@"SDRDFileObject" inManagedObjectContext:weakSelf.coreDataController._coreDataHelper.context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
NSArray * result = [weakSelf.coreDataController._coreDataHelper.context executeFetchRequest:request error:nil];
for (id fileobject in result){
[weakSelf.coreDataController._coreDataHelper.context deleteObject:fileobject];
}
[weakSelf.coreDataController._coreDataHelper.context processPendingChanges];
NSLog(@"Finished deleting all objects");
}];
});
}
The managedobjectcontext (context
) is run as type NSMainQueueConcurrencyType
and the method is run on the main thread. Suggestions for improvements, or useful examples for the combination of reset/refreshing NSOutlineView + Core Data would be greatly appreciated. Thanks. Cheers, Trond
In response to @TomHarringtons question I took a picture of my Time Profiler. I really dont understand why it hangs on this method, however, after commenting this methods out (```processPendingChanges```), it still hangs and takes forever to finish (6 minutes). It seems the process gets stuck on the main thread and can
t continue.
When I rerun the application, with processPendingChanges
commented out its still hanging.
Update
I believe I solved this but I am slightly uncertain as to why this worked. It seems that my first method went into an indefinite loop that did not release its objects. The following simple solution worked:
__weak __typeof__(self) weakSelf = self;
dispatch_sync(dispatch_get_main_queue(), ^{
[weakSelf.coreDataController._coreDataHelper.context reset];
});
I was certain that to properly empty a managed object context I would have to delete each entity individually. The reset function seems pretty brute force and does it actually clean up memory and make sure everything is okay? If anyone wants to shed some light on this that would be appreciated.