带有谓词的NSFetchedResultsController在更新后获得NSFetchedResultsChangeDelete

时间:2015-02-05 17:54:23

标签: ios core-data

NSFetchedResultsController有一个严重的问题,它有一个谓词。在为联系人的属性更新值之后会发生此问题。以便它的配置如下:

    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Contacts" inManagedObjectContext:_addressbookMainObjectContext

    NSSortDescriptor *sortNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastnameFirstLetter" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
    NSSortDescriptor *sortNameDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
    NSArray *sortDescriptors = [NSArray arrayWithObjects:sortNameDescriptor, sortNameDescriptor1, nil];

    NSFetchRequest *fetchRequest = [NSFetchRequest new];
    [fetchRequest setEntity:entityDescription];

    [fetchRequest setSortDescriptors:sortDescriptors];


    fetchRequest.predicate =  [NSPredicate predicateWithFormat:@"contactType == 3"];;

    NSFetchedResultsController *fetchedResultsController =
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                        managedObjectContext:_addressbookMainObjectContext
                                          sectionNameKeyPath:@"sectiononIdentifier"
                                                   cacheName:nil];
    _fetchResultController = fetchedResultsController;
    _fetchResultController.delegate = self;

谓词设置为获取已过滤的行。

这就是父子上下文的配置方式:

    _addressbookMainObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    _addressbookMainObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
    _addressbookMainObjectContext setParentContext:_writerContext];


    _writerContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [_writerContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
    [_writerContext setPersistentStoreCoordinator:_persistentStoreCoordinator];

用于更新行,另一个私有上下文用于完成工作:

    NSManagedObjectContext *ctx = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [ctx setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
    [ctx setParentContext:[PalDataCache sharedInstance].addressbookMainObjectContext];


    [ctx performBlockAndWait:^{
        NSError *errorAllCons = nil;
        NSArray *allCons = [context executeFetchRequest:allContacts error:&errorAllCons];

        Contacts * contact = [allCons objectAtIndex:0];
        contact.pictureUpdatedForRedownload = [NSNumber numberWithBool:YES];
    }];

所以在此临时上下文中保存更改后。 NSFetchedResultsControllerDelegate被触发:

- (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:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
        break;

    case NSFetchedResultsChangeDelete:
    {
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
        break;
    }
    case NSFetchedResultsChangeUpdate:
        [self configureCell:(contactCell*)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
        break;

    case NSFetchedResultsChangeMove:
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
        [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
        break;
}

}

这会触发NSFetchedResultsChangeDelete,导致该行从表中删除但不会从数据库中删除。在重新取消之后,一切都回到了那里。这是一个非常糟糕的用户体验。谓词是根据用户定义的过滤器设置的。如果获取请求中没有谓词,则不会发生此问题。我究竟做错了什么?是否有解决此问题的方法?

修改 当我尝试更新联系人主要上下文中的记录时,仍会出现此问题。所以它是主要的上下文和写上下文组合。

1 个答案:

答案 0 :(得分:2)

我遇到了同样的问题。这就是我修复的方法:

  1. 我的谓词使用的是(" index ==%@")
  2. 我正在过滤一个整数值,但我正在传递@" 1"。
  3. 将其更改为%i并传递整数,工作。