如果某个对象的某个属性不满足它的谓词,是否可以让NSFetchedResultsController删除一个对象?

Mic*_*ord 3 core-data objective-c nsfetchedresultscontroller ios

我有一个由对象列表填充的NSFetchedResultsController-backed UICollectionViewController.每个对象都有一个名为deleted的BOOL属性.我的fetch控制器使用以下谓词来过滤我的对象.

[NSPredicate predicateWithFormat:@"deleted == NO"];
Run Code Online (Sandbox Code Playgroud)

我的问题是当我通过将其标记为删除对象时deleted = @YES.随后的didChangeObject:方法告诉我,该对象被更新 删除.并且不会从集合视图中删除该对象.如果我退出并重新加载我的应用程序,该对象不会显示在集合视图中,这是正确的行为.

有什么东西我做错了,或者这是预期的行为NSFetchedResultsController

这里要求的更新是代码:

获取控制器配置:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"deleted == %@", @NO];
NSSortDescriptor *timestampSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timestamp" ascending:NO];
NSSortDescriptor *prioritySortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"priority" ascending:NO];
NSManagedObjectContext *managedObjectContext = [NSManagedObjectContext MR_defaultContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:[GYNotification description] inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
[request setIncludesSubentities:YES];
[request setSortDescriptors:sortDescriptors];       
[request setPredicate:predicate];

NSFetchedResultsController *aFetchedResultsController =
    [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                           managedObjectContext:managedObjectContext
                                             sectionNameKeyPath:sectionNameKeyPath
                                                      cacheName:nil];
Run Code Online (Sandbox Code Playgroud)

然后fetch控制器委托方法:

- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath {
    NSMutableDictionary *change = [NSMutableDictionary new];
    switch(type) {
        case NSFetchedResultsChangeInsert:
            change[@(type)] = newIndexPath;
            break;
        case NSFetchedResultsChangeDelete:
            change[@(type)] = indexPath;
            break;
        case NSFetchedResultsChangeUpdate:
            change[@(type)] = indexPath;
            break;
        case NSFetchedResultsChangeMove:
            change[@(type)] = @[indexPath, newIndexPath];
            break;
    }
    [_objectChanges addObject:change];
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    if ([_objectChanges count] > 0) {
        [self.collectionView performBatchUpdates:^{
            for (NSDictionary *change in _objectChanges) {
                [change enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, id obj, BOOL *stop) {
                    NSFetchedResultsChangeType type = [key unsignedIntegerValue];
                    switch (type)
                    {
                        case NSFetchedResultsChangeInsert:
                            [self.collectionView insertItemsAtIndexPaths:@[obj]];
                            break;
                        case NSFetchedResultsChangeDelete:
                            [self.collectionView deleteItemsAtIndexPaths:@[obj]];
                            break;
                        case NSFetchedResultsChangeUpdate:
                            [self.collectionView reloadItemsAtIndexPaths:@[obj]];
                            break;
                        case NSFetchedResultsChangeMove:
                            [self.collectionView moveItemAtIndexPath:obj[0] toIndexPath:obj[1]];
                            break;
                    }
                }];
            }
        } completion:nil];
    }

    [_objectChanges removeAllObjects];
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*ast 5

这种行为听起来像我期望的那样NSFetchedResultsController.您实际上只是对其中一个对象进行更新.它被命名的事实deleted没有区别.事实上,deleted在我看来,调用它有点危险,因为NSManagedObject已经有了一种isDeleted方法.

听起来你想隐藏某些托管对象而不真正删除它们.我建议将该deleted属性重命名为shouldBeVisible或者markedForDeletion.这样一来,意图就会更加清晰,并且不会有太多的混乱,因为你的对象实际处于什么状态.