A datasource will initially be totally empty (no items and no sections). Inserting items in section 0 before inserting section 0 will cause an exception to be raised.
Why not have one section by default? Because implicit/default behaviors can be confusing.
If that behavior was implemented as a default but not documented, it would be very confusing when inserting a section at index 0 on a newly created datasource will actually cause it to have two sections (we already have the one created by default).
Obviously documentation would make things better but it's easy to miss a piece of documentation...
The lifecycle of the datasource should match the lifecycle of the collection view or table view it is used with. You might otherwise end up with the content of your list view being out of sync with the internal state of the datasource and this will cause a crash eventually.
The datasource involves asynchronous operations
Each changeset is computed asynchronously by CKComponentDatasource, therefore the corresponding changes are not reflected immediately on the corresponding UITableView or UICollectionView and it is important to be careful about sources of data being out of sync.
Always ask the datasource for the model corresponding to an index path
The datasource maintains an internal data structure which is the only source of truth for the corresponding UICollectionView or UITableView. For this reason you should query the datasource to get information associated with a certain indexPath. Any other source of data may be out of sync with the current state of the list view.
For instance to access the model associated to a certain index path using a CKCollectionViewDataSource you can use:
Now let’s look at what could go wrong if we query another source of data.
Don’t ask the the list view for the position of the next insertion
The datasource gives you the current state of what is displayed on the screen, but it doesn’t include what is potentially currently being computed in the background. To get this information you need to maintain state that is updated at the same time as a changeset is enqueued.
Let’s look at this buggy code that uses the datasource to compute the insertion index.
In -insertAtTail we should check _listOfModels instead to compute the insertion index.