我发现了一个来自用户的崩溃分析,但在我的终端是不可复制的。
项目在多个地方使用集合视图,我甚至已经验证了单元格类在故事板中被正确设置。
注意:代码使用RxSwift.
任何帮助都将是非常感激的。
Fatal Exception: NSInternalInconsistencyException
the cell returned from -collectionView:cellForItemAtIndexPath: does not have a reuseIdentifier - cells must be retrieved by calling -dequeueReusableCellWithReuseIdentifier:forIndexPath:
Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x1ae60b298 __exceptionPreprocess
1 libobjc.A.dylib 0x1c2365480 objc_exception_throw
2 CoreFoundation 0x1ae518cc8 -[CFPrefsSearchListSource addManagedSourceForIdentifier:user:]
3 Foundation 0x1af850128 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
4 UIKitCore 0x1b062c7c0 -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:notify:]
5 UIKitCore 0x1b062dce8 -[UICollectionView _prefetchItemsForPrefetchingContext:maxItemsToPrefetch:]
6 UIKitCore 0x1b0635634 -[UICollectionView layoutSubviews]
7 UIKitCore 0x1b13ae6d4 -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
8 QuartzCore 0x1b1824424 -[CALayer layoutSublayers]
9 QuartzCore 0x1b182abac CA::Layer::layout_if_needed(CA::Transaction*)
10 QuartzCore 0x1b183616c CA::Layer::layout_and_display_if_needed(CA::Transaction*)
11 QuartzCore 0x1b177e578 CA::Context::commit_transaction(CA::Transaction*, double, double*)
12 QuartzCore 0x1b17a92c8 CA::Transaction::commit()
13 QuartzCore 0x1b17aa530 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)
14 CoreFoundation 0x1ae589588 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
15 CoreFoundation 0x1ae583bb8 __CFRunLoopDoObservers
16 CoreFoundation 0x1ae584154 __CFRunLoopRun
17 CoreFoundation 0x1ae583818 CFRunLoopRunSpecific
18 GraphicsServices 0x1c4c89570 GSEventRunModal
19 UIKitCore 0x1b0eaf0e8 -[UIApplication _run]
20 UIKitCore 0x1b0eb4664 UIApplicationMain
cellForItemAt
代码func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MyCollectionViewCell.identifier, for: indexPath) as? MyCollectionViewCell else{return UICollectionViewCell()}
cell.config(collectionView.tag == 1 ? dataSourceFirst[indexPath.row] : dataSourceSecond[indexPath.row])
return cell
}
对于面临同样问题的人:return UICollectionViewCell()
正在导致崩溃。
不要把UICollectionViewCell和UITableViewCell混在一起,初始化后返回是安全的。
修复方法非常简单:
- 在集合视图设置过程中为重用标识符注册单元格类型
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
- 而不是init (
return UICollectionViewCell()
)只是为相同的标识符脱队列相同的细胞类型。collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
在我的例子中是这样的:
func setupCollectionView() {
...
collectionView.registerCell(EmptyCell.self)
...
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let controller = controller else {
//instead of return UICollectionViewCell()
return collectionView.dequeueCell(EmptyCell.self, indexPath: indexPath).setup(.songDetails)
}
let cell = collectionView.dequeueCell(SectionSongMenuCell.self, indexPath: indexPath)
...
return cell
}
***
extension UICollectionView {
func registerCell<T: UICollectionViewCell>( _ type: T.Type) {
self.register(type.nib, forCellWithReuseIdentifier: type.identifier)
}
func dequeueCell<T: UICollectionViewCell>(_ type: T.Type, indexPath: IndexPath) -> T {
return self.dequeueReusableCell(
withReuseIdentifier: type.identifier,
for: indexPath) as! T
}
}