Reputation:
This is the error I am getting on devices with iOS 9 and 10 :
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'request for number of items before section 9223372036854775807 when there are only 1 sections in the collection view'
The error seems clear to me, however I am unable to understand why this is not happening on devices with iOS 11.
I don't know how to fix it.
Here is my code :
extension MainTileViewController: MainForecastsDelegate {
func mainForecasts(_ forecastVC: MainForecastsViewController!, didChangeWith object: Any!) {
if let cell = self.outletWeatherForecastCollectionView.cellForItem(at: self.currentIndexPath) as? MainTileCollectionViewCell {
// Some stuff...
}
}
The crash happens here. This is a protocol method triggered when the user switch day etc...
Obviously I have an issue with my currentIndexPath.
Here is my initialization :
var currentIndexPath : IndexPath = []
And in the viewDidLoad :
self.currentIndexPath = IndexPath(item: 0, section: 0)
How can I secure my code so that it won't crash ? Can you explain me the changing behavior between collectionView from iOS 9/10 with iOS 11 ones (except prefetching).
Upvotes: 1
Views: 454
Reputation: 12015
What's happening is that setting currentIndexPath = []
is not assigning any value to its item
or section
; it's creating an "empty" IndexPath (IndexPath objects are basically arbitrary-length tuples or arrays of values and can be created/manipulated as such). Any code attempting to use it in that way (such as passing it to a cellForItem
call) will have potentially undefined behavior. Looks like something is effectively interpreting the missing section
value as -1, and then something else is interpreting that -1 as an unsigned 64-bit integer.
Instead, if you want to use the same general logic that you have now, I'd suggest declaring indexPath
as an optional:
var currentIndexPath: IndexPath?
Then, use if-let syntax in your usages of currentIndexPath:
extension MainTileViewController: MainForecastsDelegate {
func mainForecasts(_ forecastVC: MainForecastsViewController!, didChangeWith object: Any!) {
if let currentIndexPath = currentIndexPath,
let cell = outletWeatherForecastCollectionView.cellForItem(at: currentIndexPath) as? MainTileCollectionViewCell {
// Some stuff...
}
}
This follows Swift idioms and makes clear the concept that you start with an "unknown" index path.
But - as @picciano's answer suggests, you may want to rethink your overall design to better fit the larger design patterns of iOS apps.
Upvotes: 3
Reputation: 22701
I would suggest changing your approach a bit. Let your collection view cell subclass be responsible for updating itself, perhaps from a notification. Trying to retain an index path or reference to a cell will always be problematic given their tendency to be reused.
Upvotes: 0