我使用NSFetchedResultsController和UICollectionView。每当我从服务器接到电话时,我都会更新Core数据表,并使用核心数据通知更新UICollectionView。当我这样做时,我收到这样的错误,
CoreData:错误:严重的应用程序错误。抓住了一个例外 在调用期间来自NSFetchedResultsController的委托 -controllerDidChangeContent :.无效更新:第0部分中的项目数无效。现有部分中包含的项目数 更新(12)后必须等于包含的项目数 在更新前的那一节(11)中,加上或减去数量 从该部分插入或删除的项目(0已插入,0已删除) 加上或减去移入或移出的物品数量 部分(0移入,0移出)。 with userInfo(null)
从这个帖子Assertion failure when i use the Add Function
我知道我的Collectionview在进行更新时正在更新。我的问题是,我该如何防止这种情况?
我的代码:
(void)controllerDidChangeContent:(NSFetchedResultsController *)controller { @synchronized(个体经营) { if(controller == myFetchedResultsController) { if([self.sectionChangesInCollectionView count]> 0) { [self.myCollectionView performBatchUpdates:^ {
for (NSDictionary *change in self.sectionChangesInCollectionView) { [change enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, id obj, BOOL *stop)
{
NSFetchedResultsChangeType type = [key unsignedIntegerValue]; switch (type) { case NSFetchedResultsChangeInsert: [self.myCollectionView insertSections:[NSIndexSet indexSetWithIndex:[obj
unsignedIntegerValue]]]; 打破; case NSFetchedResultsChangeDelete: [self.myCollectionView deleteSections:[NSIndexSet indexSetWithIndex:[obj unsignedIntegerValue]]]; 打破; case NSFetchedResultsChangeUpdate: [self.myCollectionView reloadSections:[NSIndexSet indexSetWithIndex:[obj unsignedIntegerValue]]]; 打破; } }]; } 完成:nil]; }
if ([self.objectChangesInCollectioView count] > 0 && [self.sectionChangesInCollectionView count] == 0) { if ([self shouldReloadCollectionViewToPreventKnownIssue] ||
self.myCollectionView.window == nil){ //这是为了防止UICollectionView中出现错误。 //在插入第一个对象或删除集合视图中的最后一个对象时,该错误会自动出现。 // UICollectionView Assertion failure //修复错误后,应删除此代码,并在OpenRadar中对其进行跟踪 // http://openradar.appspot.com/12954582 [self.myCollectionView reloadData];
} else { [self.myCollectionView performBatchUpdates:^{ for (NSDictionary *change in self.objectChangesInCollectioView) { [change enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, id obj, BOOL *stop)
{
NSFetchedResultsChangeType type = [key unsignedIntegerValue]; switch (type) { case NSFetchedResultsChangeInsert: { dispatch_async(dispatch_get_main_queue(), ^ { [self.myCollectionView insertItemsAtIndexPaths:@[obj]]; }); break; } case NSFetchedResultsChangeDelete: { dispatch_async(dispatch_get_main_queue(), ^ { [self.myCollectionView deleteItemsAtIndexPaths:@[obj]]; }); break; } case NSFetchedResultsChangeUpdate: { dispatch_async(dispatch_get_main_queue(), ^ { [self.myCollectionView reloadItemsAtIndexPaths:@[obj]]; }); break; } case NSFetchedResultsChangeMove: { dispatch_async(dispatch_get_main_queue(), ^ { [self.myCollectionView moveItemAtIndexPath:obj[0]
toIndexPath:OBJ 1]; }); 打破; } } }]; } 完成:nil]; } }
[self.sectionChangesInCollectionView removeAllObjects]; [self.objectChangesInCollectioView removeAllObjects]; } else { }
}}
pragma mark - collectionView错误修复方法
(BOOL)shouldReloadCollectionViewToPreventKnownIssue { __block BOOL shouldReload = NO;
for(NSDictionary *在self.objectChangesInCollectioView中更改){ [更改enumerateKeysAndObjectsUsingBlock:^(id key,id obj,BOOL * stop){ NSFetchedResultsChangeType type = [key unsignedIntegerValue]; NSIndexPath * indexPath = obj; 开关(类型){ case NSFetchedResultsChangeInsert: if([self.myCollectionView numberOfItemsInSection:indexPath.section] == 0){ shouldReload = YES; } else { shouldReload = NO; } 打破; case NSFetchedResultsChangeDelete: if([self.myCollectionView numberOfItemsInSection:indexPath.section] == 1){ shouldReload = YES; } else { shouldReload = NO; } 打破; case NSFetchedResultsChangeUpdate: shouldReload = NO; 打破; case NSFetchedResultsChangeMove: shouldReload = NO; 打破; } }]; }
return shouldReload; }