gpt4 book ai didi

ios - 在另一个上下文中发生更改后,如何正确地从 NSFetchedResultsController 执行Fetch?

转载 作者:行者123 更新时间:2023-11-29 02:20:57 25 4
gpt4 key购买 nike

当我在另一个具有自己的上下文的顶层 Controller 中进行一些更改时,我会向 UITableViewController 类发布更新单元格的通知。此通知在将 fetchedResultsController 设置为 nil 后调用 performFetch。但只有当我完全重新加载 UITableViewController 时,我才会看到这种变化。我没有使用缓存。如何在更新我的 PersistentStore 后立即刷新 tableView 单元格?

- (void)performFetch {
NSError *error = nil;

_fetchedResultsController = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unable to perform fetch. Reason: %@", [error localizedDescription]);
}
[self.tableView reloadData];
}


- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController) {
return _fetchedResultsController;
} else {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"orderingValue" ascending:YES];
[request setSortDescriptors:@[sort]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"syncStatus != %d", ObjectDeleted];
[request setEntity:entity];
[request setFetchBatchSize:20];
[request setPredicate:predicate];

NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
_fetchedResultsController = fetchedResultsController;
_fetchedResultsController.delegate = self;
}

return _fetchedResultsController;
}

更新:这是 FetchedResultsController 委托(delegate)方法:

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {

UITableView *tableView = self.tableView;

switch(type) {

case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeUpdate:
[self configureCell:(ItemCell *)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;

case NSFetchedResultsChangeMove:
break;
}
}

UITableViewController 的上下文:

self.managedObjectContext = [[CoreDataController sharedInstance] newManagedObjectContext];

DetailsViewController 的上下文:

self.managedObjectContext = [[CoreDataController sharedInstance] masterManagedObjectContext];

核心数据 Controller :

- (NSManagedObjectContext *)masterManagedObjectContext {
if (_masterManagedObjectContext != nil) {
return _masterManagedObjectContext;
}

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_masterManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_masterManagedObjectContext performBlockAndWait:^{
[_masterManagedObjectContext setPersistentStoreCoordinator:coordinator];
}];

}
return _masterManagedObjectContext;
}

- (NSManagedObjectContext *)newManagedObjectContext {
NSManagedObjectContext *newContext = nil;
NSManagedObjectContext *masterContext = [self masterManagedObjectContext];
if (masterContext != nil) {
newContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[newContext performBlockAndWait:^{
[newContext setParentContext:masterContext];
}];
}

return newContext;
}

最佳答案

我不确定您的完整设置涉及什么,但您确实需要实现 NSFetchedResultsControllerDelegate 协议(protocol)方法来动态更新您的 TableView 单元格。 https://developer.apple.com/library/prerelease/ios/documentation/CoreData/Reference/NSFetchedResultsControllerDelegate_Protocol/index.html

如果您使用不同的托管对象上下文进行更新,则在这些更改反射(reflect)到您的上下文中之前,您还必须合并这些更改。

更新1

[[NSNotificationCenter defaultCenter]
addObserverForName:NSManagedObjectContextDidSaveNotification
object:nil
queue:nil
usingBlock:^(NSNotification* note) {
NSManagedObjectContext *moc = self.managedObjectContext;
if (note.object != moc) {
[moc performBlock:^(){
[moc mergeChangesFromContextDidSaveNotification:note];
}];
}
}];

更新2

您可以将以下模板用于 NSFetchedResultsControllerDelegate

#pragma mark - NSFetchedResultsControllerDelegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller
didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex
forChangeType:(NSFetchedResultsChangeType)type
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;

default:
break;
}
}


- (void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeUpdate:
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeMove:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
}

关于ios - 在另一个上下文中发生更改后,如何正确地从 NSFetchedResultsController 执行Fetch?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28141449/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com