objective-c - UICollectionView 在包含标题时不会重新加载项目

标签 objective-c cocoa-touch core-data ios6 uicollectionview

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

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

在我的 AlbumViewController 中,我使用 NSFetchedResultsController 获取所有 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 实例被启动并推送到我的导航 Controller 上。在这种情况下,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:parentAlbum 对象的类型 NSFetchedResultsChangeUpdate 调用.当前的 NSFetchedResultsController 中不存在那个。所以当它试图在 Collection View 中更新它时失败了。

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

编辑:
发布问题后,我意识到实际上不是 NSFetchedResultsController 通知了错误的对象。但它会通知前一个(父) Collection View 中的对象,但它会通知它自己的 Collection View Controller 。

但这可能就是问题所在; Collection View Controller 在不可见时收到通知,看起来目前无法处理。我这样处理通知:

- (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 header (补充 View )后它再次工作。

因此:当我的 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

最佳答案

我不知道这是解决方案还是变通方法,但是如果您在 viewWillDisappear 中释放获取的结果 Controller :

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

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

这避免更新当前不可见的 Collection View 。

因为您已经在 viewWillAppear 中访问 FRC:

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

由于 FRC 的惰性设置函数,当 View 再次可见时将重新创建 FRC。

关于objective-c - UICollectionView 在包含标题时不会重新加载项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12718689/

相关文章:

ios - 当单元格插入表格时,自定义表格 View 单元格内的 ImageView 消失

ios - 如何使用 Swift 4 的 MagicalRecord 正确获取数据?

objective-c - 单击返回按钮时添加功能 -ios

objective-c - IOS复制 "drop pin"效果

cocoa-touch - 测量字符串的像素宽度

ios - 如何在非 UI 线程上将 PDF 页面的图像预览存储到磁盘?

iphone - 在导航栏iPhone上设置自定义后退按钮,有时会在顶部显示后退按钮

ios - 我如何知道私有(private)框架方法的参数必须是哪种类型?

objective-c - 跳跃动画 : First animation duration doesn't work. IOS

ios - 核心数据导致 endUpdates 异常