Modern collection views use UICollectionViewDiffableDataSource
with UICollectionView.CellRegistration
and UICollectionView.dequeueConfiguredReusableCell(registration:indexPath:item)
.
There are runtime crashes when passing nil as argument for the item parameter. There's no clear documentation on whether optional items are allowed or not.
The function signature in Swift is:
@MainActor @preconcurrency func dequeueConfiguredReusableCell<Cell, Item>(using registration: UICollectionView.CellRegistration<Cell, Item>, for indexPath: IndexPath, item: Item?) -> Cell where Cell : UICollectionViewCell
Given the Item?
type one would assume Optionals are allowed.
In Objective-C the signature is:
- (__kindof UICollectionViewCell *)dequeueConfiguredReusableCellWithRegistration:(UICollectionViewCellRegistration *)registration forIndexPath:(NSIndexPath *)indexPath item:(id)item;
I'm not sure, if there's implicit nullability bridging to the Swift API or if the Objective-C files has some explicit nullability annotation.
The crash is due to a swift_dynamicCast
failing with:
Could not cast value of type '__SwiftNull' (0x10b1c4dd0) to 'Item' (0x10d6086e0).
It's possible to workaround this by making a custom Optional type like
enum MyOptional<T> {
case nothing
case something(T)
}
and then wrapping and unwrapping Item?
to MyOptional<Item>
. But this feels like unnecessary boilerplate.
With the current situation it's easy to ship an app where everything seems to work, but in production only certain edge cases cause nil values being used and then crashing the app.
- Please clarify the allowed arguments / types for the
dequeueConfiguredReusableCell
function. - Either Optionals should be supported and not crash at runtime or the signatures should be changed so there's a compile time error, when trying to use an
Item?
.
Feedback: FB16494078