【发布时间】:2014-10-20 02:23:13
【问题描述】:
我将 NSFetchedResultsController 与 UICollectionView 一起使用。每当我接到来自服务器的呼叫时,我都会更新核心数据表,并通过使用核心数据通知来更新 UICollectionView。当我这样做时,我会收到这样的错误,
CoreData:错误:严重的应用程序错误。捕获到异常 在调用期间从 NSFetchedResultsController 的委托 -controllerDidChangeContent:。无效更新:第 0 节中的项目数无效。现有节中包含的项目数 更新后 (12) 必须等于包含的项目数 在更新之前的那个部分(11),加减数 从该部分插入或删除的项目(0 插入,0 删除) 加上或减去移入或移出的项目数 部分(0 移入,0 移出)。与 userInfo (null)
来自这个帖子Assertion failure when i use the Add Function
我了解我的 Collectionview 在更新时正在更新。我的问题是,我怎样才能防止这种情况发生?
我的代码:
(void)controllerDidChangeContent:(NSFetchedResultsController *)controller { @同步(自我) { 如果(控制器 == myFetchedResultsController) { if ([self.sectionChangesInCollectionView 计数] > 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无符号整数值]]]; 休息; 案例 NSFetchedResultsChangeDelete: [self.myCollectionView deleteSections:[NSIndexSet indexSetWithIndex:[obj 无符号整数值]]]; 休息; 案例 NSFetchedResultsChangeUpdate: [self.myCollectionView reloadSections:[NSIndexSet indexSetWithIndex:[obj 无符号整数值]]]; 休息; } }]; } } 完成:无]; }
if ([self.objectChangesInCollectioView count] > 0 && [self.sectionChangesInCollectionView count] == 0) { if ([self shouldReloadCollectionViewToPreventKnownIssue] ||self.myCollectionView.window == nil) { // 这是为了防止 UICollectionView 中的 bug 发生。 // 在集合视图中插入第一个对象或删除最后一个对象时会出现该错误。 //UICollectionView Assertion failure // 一旦 bug 被修复,这段代码应该被删除,它在 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:obj1]; }); 休息; } } }]; } } 完成:无]; } }
[self.sectionChangesInCollectionView removeAllObjects]; [self.objectChangesInCollectioView removeAllObjects]; } else { }} }
pragma mark - collectionView bug 修复方法
(BOOL) 应该重新加载CollectionViewToPreventKnownIssue { __block BOOL shouldReload = NO;
for (NSDictionary *更改 self.objectChangesInCollectioView) { [更改 enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { NSFetchedResultsChangeType 类型 = [key unsignedIntegerValue]; NSIndexPath *indexPath = obj; 开关(类型){ 案例 NSFetchedResultsChangeInsert: if ([self.myCollectionView numberOfItemsInSection:indexPath.section] == 0) { 应该重新加载=是; } 别的 { 应该重新加载=否; } 休息; 案例 NSFetchedResultsChangeDelete: if ([self.myCollectionView numberOfItemsInSection:indexPath.section] == 1) { 应该重新加载=是; } 别的 { 应该重新加载=否; } 休息; 案例 NSFetchedResultsChangeUpdate: 应该重新加载=否; 休息; 案例 NSFetchedResultsChangeMove: 应该重新加载=否; 休息; } }]; }
返回应该重新加载; }
【问题讨论】:
标签: iphone core-data ios7 uicollectionview nsfetchedresultscontroller