NSManagedObjectContext and NSArrayController reset/refresh problem

时光毁灭记忆、已成空白 提交于 2019-12-01 19:39:12

I don't think two processes are supposed to work in the same Core Data database. It is probably better to let one process act as a server that owns (and opens) the database and let the other send it commands to make changes. I don't think Core Data was ever meant to support multiple processes talking to the same db.

So I've been playing around with this exact situation, and I will not contradict the first answer-- you're probably not supposed to do this, and if you have to, maybe iCloud works. Don't use this code. I provide it to help others get to the point where they can discover all the issues I didn't fix, and move on.

That said, you can do what the original question was looking to do-- force the controller to reload from disk:

// Tear down bindings and context, create new context & rebind
[self.watcherAC unbind:@"managedObjectContext"];
[self saveAction:self]; // Optional, dependent on NSMergePolicy, etc
self.managedObjectContext = [[NSManagedObjectContext alloc] init];
self.managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
[self.managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];
[self.watcherAC bind:@"managedObjectContext" toObject:self withKeyPath:@"managedObjectContext" options:nil];

// Force controller to refetch and rearrange
NSError* error;
[self.watcherAC fetchWithRequest:nil merge:NO error:&error];  // Immediate fetch
[self.watcherAC prepareContent];
[self.watcherAC rearrangeObjects];

That refreshes the tableView's content from the store on disk. (The tableView is bound to the watcherAC array controller)

I found that fetch: isn't immediate-- it's done the next time through the run loop for the application. So to have fetch / rearrange done in the right order, you need to use fetchWithRequest:

I'm not sure prepareContent: is needed, though it may have helped clear up faults in the controller content.

I have not been able to get it to restore the tableView selection, though that may be because I do this within a tableview delegate call, so the view's selection gets out of synch with the controller's selection no matter what hacks I try. Maybe this could work for someone, but I suggest trying to figure out how to not allocate a new MOC once your view has bindings to it.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!