views:

112

answers:

1

I have a UITableView backed by an NSFetchedResultsController which may trigger updates at any time. If the user is currently reordering rows, applying these updates will cause an exception because the table view has temporarily taken over and you get an error like

Invalid update: invalid number of rows in section [...]

How can I detect when the user has started moving a cell so I can delay updates caused by the fetched results controller? There don't seem to be any table view delegate methods to detect this. This delegate method:

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {

Doesn't get called when the user initially detaches the first cell, only when they actually move it somewhere else.

One solution is to check isEditing in the fetched results callbacks and just do a bulk reloadData rather than dynamically inserting/deleting rows, but I'm wondering if there is a way to check specifically for the 'reordering' mode.

A: 

Before a table moves a row it sends...

– tableView:canMoveRowAtIndexPath:

... to its data source. You can put a edit lock there which will take effect before the cell actually moves.

You might want to rethink your design some. It sounds like you have a data-model which can be modified by two different sources simultaneously. If so, then you need to set up some kind of concurrency lock within the data-model itself so the two modifications can't actually occur at the same time. Simultaneous modifications won't just cause problems with the UI but with anything that uses the data-model.

TechZen
But potentially the tableview could call that at a time other than just before moving a cell. It isn't documented that this is always called just before moving a cell so relying on that behaviour isn't likely to be future proof. And my data model is fine, I'm merging changes into the core data model in the standard way so change requests are properly sent out on the main thread.
Mike Weller
This method is called every time before the UI moves a cell. It isn't called when the datamodel drives a change. It's sole purpose is to check that an UI event can move the cell. You're going to have to set flags to prevent either the data or the user from altering the table while the other is doing it. You've got a race condition.
TechZen