Reset Data-driven Data Content Using Core DataController

I run my program, which creates the contents of the master data, which is displayed in NSOutlineView using NSTreeController . The second time I run my program, I want to clear the contents of my NSTreeController , and I run the method inserted below. The method either freezes for a long time (600 seconds) before it ends, or it will work. If I have few (500-1000) objects in my NSTreeController , it takes much less time than if I have many (200,000) objects to pass this method, if it passes at all. I need to know if there is a better way to clear / update / reset the contents of my NSTreeController in order to clear my NSoutlineView before starting the program again and filling in the NSTreeController again. In particular, I would like my NSoutlineView to respond quickly to changes in the contents of my NSTreeController , and I need the contents of my master data managed by NSTreeController 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 context managed object is started as the type NSMainQueueConcurrencyType , and the method is started in the main thread. Improvement suggestions or useful examples for the reset / refreshing NSOutlineView + Core Data combination are welcome. Thank you Cheers, Trond

In response to a @TomHarringtons question, I took a snapshot of my Time Profiler. I really continue t 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 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.

enter image description here

When I restart the application, processPendingChanges commented out it was still hanging.

enter image description here

Update

I believe I solved it, but I'm not sure why it worked. It seems that my first method went into an indefinite loop that did not release its objects. The following simple solution was implemented:

  __weak __typeof__(self) weakSelf = self; dispatch_sync(dispatch_get_main_queue(), ^{ [weakSelf.coreDataController._coreDataHelper.context reset]; }); 

I was sure that for the correct removal of the context of the managed object, I would have to delete each object individually. Does the reset function seem pretty brute force and does it really clear the memory and do everything okay? If someone wants to shed light on this, it will be appreciated.

+6
source share
1 answer

Looking at it again, you retrieved all the type objects in performBlockAndWait - this blocks the main thread, because you have mainQueueConcurrency, and you used the andWait version to execute Block.

Then you delete each object one by one. These objects are in the data structure of the tree with the outline view enabled (see KVO messages in the stack trace). These objects have many relationships that must be supported by master data, hell, you can even have a cascading delete rule. (see propagateDelete and maintainInverseRelationship in the stack trace). In any case, you begin to request that both the data source and the view begin to do a lot of work in the main thread. You can try using a child MOC with privateQueueConcurrency if you want to iterate over all objects in the background.

But, as stated in the comments:

NSManagedObjectContext reset most definitely frees up memory, and thatโ€™s fine for what you want to do here: delete everything.

He asks why you load the model from the repository on disk in the first place.

If you need Core Data, but not persistence between the times the program starts, you can initialize the persistentStoreCoordinator with NSInMemoryStoreType instead of pointing to the file URL.

+1
source

Source: https://habr.com/ru/post/979210/


All Articles