3

编辑:最初的问题是错误的,所以有些内容可能有点不相关。但可能会让你对我做事的方式有更好的印象。

我有一个非常奇怪的问题NSFetchedResultsController。首先,我将描述我的应用程序的当前情况。我有多个AlbumPhoto实体,它们都是抽象类的子类AbstractItem

在我AlbumViewController的中,我使用 to aNSFetchedResultsController来获取所有AbstractItem当前的superAlbum. 像这样:

- (NSFetchedResultsController *)fetchedResultsController {
    if (!fetchedResultsController ) {
        NSFetchRequest *request = [[NSFetchRequest alloc] init];

        [request setEntity:[NSEntityDescription entityForName:@"AbstractItem"
                                       inManagedObjectContext:managedObjectContext]];

        [request setSortDescriptors:@[
         [NSSortDescriptor sortDescriptorWithKey:@"type" ascending:YES],
         [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES],
         [NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]
        ]];

        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"superAlbum = %@", self.parentAlbum];
        [request setPredicate:predicate];

        NSFetchedResultsController *newController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                                        managedObjectContext:managedObjectContext
                                                                                          sectionNameKeyPath:@"type"
                                                                                                   cacheName:nil];

        newController.delegate = self;

        self.fetchedResultsController = newController;
    }

    return fetchedResultsController;
}

当我选择 时Album,会启动另一个实例AlbumViewController并将其推送到我的导航控制器上。在这种情况下parentAlbum,设置为选定的对象。

现在,当我Album使用以下代码添加新内容时,会发生错误。

Album *album = (Album *)[Album itemInManagedObjectContext:self.managedObjectContext];
album.name = @"Test album";
album.superAlbum = self.parentAlbum;

NSError *error;
BOOL success = [self.managedObjectContext save:&error];

if (!success) {
    NSLog(@"Error: %@", error);
}

使用对象controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:的类型调用该方法。那个在 current 中不存在。因此,当它尝试在集合视图中更新它时会失败。NSFetchedResultsChangeUpdateparentAlbumNSFetchedResultsController

不在当前中的对象怎么可能NSFetchedResultsController用于通知?我该如何解决这个问题?

编辑:
发布问题后,我意识到这实际上不是NSFetchedResultsController关于错误对象的通知。但它会通知上一个(父)集合视图中的对象,但它会对它自己的集合视图控制器执行此操作。

但这可能只是问题所在;集合视图控制器在不可见时收到通知,看起来它目前无法处理。我这样处理通知:

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {    
    switch (type) {
        case NSFetchedResultsChangeUpdate:
            [self.collectionView reloadItemsAtIndexPaths:@[indexPath]];
            break;
    }
}

我很确定它以前工作得很好。在迭代自上次提交以来所做的更改后,我让它再次工作。在我删除UICollectionView标题(补充视图)后它再次起作用。

所以:UICollectionView当项目有标题并且当前不可见时,我无法更新项目。这是一个很难发现的问题,但是如何解决呢?认为这是一个非常奇怪的问题。

我得到的错误:

2012-10-04 11:54:21.148 PhotoLibrary[9195:c07] -[NSISObjectiveLinearExpression coefficientForVariable:]: unrecognized selector sent to instance 0x968bae0
2012-10-04 11:54:21.151 PhotoLibrary[9195:c07] CoreData: error: Serious application error.  Exception was caught during Core Data change processing.  This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.  -[NSISObjectiveLinearExpression coefficientForVariable:]: unrecognized selector sent to instance 0x968bae0 with userInfo (null)
2012-10-04 11:54:21.156 PhotoLibrary[9195:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSISObjectiveLinearExpression coefficientForVariable:]: unrecognized selector sent to instance 0x968bae0'
*** First throw call stack:
(0x2977012 0x1418e7e 0x2a024bd 0x2966bbc 0x296694e 0xcb06c3 0xcb569c 0xcbf88e 0x58c670 0x5945bd 0x29198fd 0x594605 0x29198fd 0x594605 0x29198fd 0x594605 0x5946c7 0x9cd53 0x5525ff 0x9ea5c 0x5522f7 0x565228 0x56231b 0x55ed4e 0x55edf0 0x8f56 0x1242c1a 0xbcddc9 0x29d10c5 0x292befa 0xb02482 0x11545f3 0x11ede5f 0x114fa26 0x115316e 0x55dc 0x85e5 0x4312c1 0x142c705 0x57920 0x578b8 0x118671 0x118bcf 0x117d38 0x8733f 0x87552 0x653aa 0x56cf8 0x20badf9 0x20baad0 0x28ecbf5 0x28ec962 0x291dbb6 0x291cf44 0x291ce1b 0x20b97e3 0x20b9668 0x5465c 0x26bd 0x25e5)
libc++abi.dylib: terminate called throwing an exception
4

1 回答 1

5

我不知道这是解决方案还是解决方法,但是如果您在以下位置发布获取的结果控制器viewWillDisappear

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    self.fetchedResultsController = nil;
}

那么您的 ErrorTest 程序就不会再崩溃并且似乎可以正常工作。

这避免了对当前不可见的集合视图的更新。

由于您已经在访问 FRC viewWillAppear

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // ...    
    NSError *error = nil;
    BOOL success = [self.fetchedResultsController performFetch:&error];
    // ...
}

由于 FRC 的惰性设置器功能,当视图再次可见时,FRC 将重新创建。

于 2012-10-06T16:25:53.440 回答