CollectionViewController.m line 439
__50-[CollectionViewController photoLibraryDidChange:]_block_invoke
致命异常:NSInternalInconsistencyException
尝试删除并重新加载相同的索引路径({length = 2,path = 0 – 26007})
- (void)photoLibraryDidChange:(PHChange *)changeInstance { // Call might come on any background queue. Re-dispatch to the main queue to handle it. dispatch_async(dispatch_get_main_queue(),^{ // check if there are changes to the assets (insertions,deletions,updates) PHFetchResultChangeDetails *collectionChanges = [changeInstance changeDetailsForFetchResult:self.assetsFetchResults]; if (collectionChanges) { // get the new fetch result self.assetsFetchResults = [collectionChanges fetchResultAfterChanges]; UICollectionView *collectionView = self.collectionView; if (![collectionChanges hasIncrementalChanges] || [collectionChanges hasMoves]) { // we need to reload all if the incremental diffs are not available [collectionView reloadData]; } else { // if we have incremental diffs,tell the collection view to animate insertions and deletions [collectionView performBatchUpdates:^{ NSIndexSet *removedindexes = [collectionChanges removedindexes]; if ([removedindexes count]) { [collectionView deleteItemsAtIndexPaths:[removedindexes aapl_indexPathsFromIndexesWithSection:0]]; } NSIndexSet *insertedindexes = [collectionChanges insertedindexes]; if ([insertedindexes count]) { [collectionView insertItemsAtIndexPaths:[insertedindexes aapl_indexPathsFromIndexesWithSection:0]]; } NSIndexSet *changedindexes = [collectionChanges changedindexes]; if ([changedindexes count]) { [collectionView reloadItemsAtIndexPaths:[changedindexes aapl_indexPathsFromIndexesWithSection:0]]; } } completion:NULL]; } [self resetCachedAssets]; } }); }
我无法复制这个问题.可能是什么问题呢?非常感谢!
解决方法
我今天能够再现这个.为此,您需要:
>打开正在监听更改的应用程序
>打开照片应用程序,将一组照片从iCloud共享相册保存到您的照片库
>转到照片应用程序,删除其中的一些照片
>再次转到iCloud共享相册,并再次保存您删除的一些照片.你会看到这种情况发生.
我发现一个更新的代码似乎在这里更好地处理更新行为:
https://developer.apple.com/library/ios/documentation/Photos/Reference/PHPhotoLibraryChangeObserver_Protocol/
但是它仍然不会处理这种情况,也不会在要删除的索引更大时(即由于未捕获的异常’NSInternalInconsistencyException’终止应用程序),原因是:尝试从第0部分删除第9项,其中只包含9个更新前的项目).我创建了这个代码更新版本,处理这个更好,迄今为止还没有为我崩溃.
func photoLibraryDidChange(changeInfo: PHChange!) { // Photos may call this method on a background queue; // switch to the main queue to update the UI. dispatch_async(dispatch_get_main_queue()) { // Check for changes to the list of assets (insertions,moves,or updates). if let collectionChanges = changeInfo.changeDetailsForFetchResult(self.assetsFetchResult) { // Get the new fetch result for future change tracking. self.assetsFetchResult = collectionChanges.fetchResultAfterChanges if collectionChanges.hasIncrementalChanges { // Get the changes as lists of index paths for updating the UI. var removedpaths: [NSIndexPath]? var insertedpaths: [NSIndexPath]? var changedpaths: [NSIndexPath]? if let removed = collectionChanges.removedindexes { removedpaths = self.indexPathsFromIndexSetWithSection(removed,section: 0) } if let inserted = collectionChanges.insertedindexes { insertedpaths = self.indexPathsFromIndexSetWithSection(inserted,section: 0) } if let changed = collectionChanges.changedindexes { changedpaths = self.indexPathsFromIndexSetWithSection(changed,section: 0) } var shouldReload = false if changedpaths != nil && removedpaths != nil{ for changedpath in changedpaths!{ if contains(removedpaths!,changedpath){ shouldReload = true break } } } if removedpaths?.last?.item >= self.assetsFetchResult.count{ shouldReload = true } if shouldReload{ self.collectionView.reloadData() }else{ // Tell the collection view to animate insertions/deletions/moves // and to refresh any cells that have changed content. self.collectionView.performBatchUpdates( { if let theRemovedpaths = removedpaths { self.collectionView.deleteItemsAtIndexPaths(theRemovedpaths) } if let theInsertedpaths = insertedpaths { self.collectionView.insertItemsAtIndexPaths(theInsertedpaths) } if let theChangedpaths = changedpaths{ self.collectionView.reloadItemsAtIndexPaths(theChangedpaths) } if (collectionChanges.hasMoves) { collectionChanges.enumerateMovesWithBlock() { fromIndex,toIndex in let fromIndexPath = NSIndexPath(forItem: fromIndex,inSection: 0) let toIndexPath = NSIndexPath(forItem: toIndex,inSection: 0) self.collectionView.moveItemAtIndexPath(fromIndexPath,toIndexPath: toIndexPath) } } },completion: nil) } } else { // Detailed change information is not available; // repopulate the UI from the current fetch result. self.collectionView.reloadData() } } } } func indexPathsFromIndexSetWithSection(indexSet:NSIndexSet?,section:Int) -> [NSIndexPath]?{ if indexSet == nil{ return nil } var indexPaths:[NSIndexPath] = [] indexSet?.enumerateIndexesUsingBlock { (index,Bool) -> Void in indexPaths.append(NSIndexPath(forItem: index,inSection: section)) } return indexPaths }
Swift 3 / iOS 10版本:
func photoLibraryDidChange(_ changeInstance: PHChange) { guard let collectionView = self.collectionView else { return } // Photos may call this method on a background queue; // switch to the main queue to update the UI. dispatchQueue.main.async { guard let fetchResults = self.fetchResults else { collectionView.reloadData() return } // Check for changes to the list of assets (insertions,or updates). if let collectionChanges = changeInstance.changeDetails(for: fetchResults) { // Get the new fetch result for future change tracking. self.fetchResults = collectionChanges.fetchResultAfterChanges if collectionChanges.hasIncrementalChanges { // Get the changes as lists of index paths for updating the UI. var removedpaths: [IndexPath]? var insertedpaths: [IndexPath]? var changedpaths: [IndexPath]? if let removed = collectionChanges.removedindexes { removedpaths = self.indexPaths(from: removed,section: 0) } if let inserted = collectionChanges.insertedindexes { insertedpaths = self.indexPaths(from:inserted,section: 0) } if let changed = collectionChanges.changedindexes { changedpaths = self.indexPaths(from: changed,section: 0) } var shouldReload = false if let removedpaths = removedpaths,let changedpaths = changedpaths { for changedpath in changedpaths { if removedpaths.contains(changedpath) { shouldReload = true break } } } if let item = removedpaths?.last?.item { if item >= fetchResults.count { shouldReload = true } } if shouldReload { collectionView.reloadData() } else { // Tell the collection view to animate insertions/deletions/moves // and to refresh any cells that have changed content. collectionView.performBatchUpdates({ if let theRemovedpaths = removedpaths { collectionView.deleteItems(at: theRemovedpaths) } if let theInsertedpaths = insertedpaths { collectionView.insertItems(at: theInsertedpaths) } if let theChangedpaths = changedpaths { collectionView.reloadItems(at: theChangedpaths) } collectionChanges.enumerateMoves { fromIndex,toIndex in collectionView.moveItem(at: IndexPath(item: fromIndex,section: 0),to: IndexPath(item: toIndex,section: 0)) } }) } } else { // Detailed change information is not available; // repopulate the UI from the current fetch result. collectionView.reloadData() } } } } func indexPaths(from indexSet: IndexSet?,section: Int) -> [IndexPath]? { guard let set = indexSet else { return nil } return set.map { (index) -> IndexPath in return IndexPath(item: index,section: section) } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。