The short answer is that you need to buffer the data in your data model and only update the table with the new data when the table is not being scrolled. That needs to be done in the data model because the datasource delegate has no idea what is inside the data model or what has changed.
However, from a UI design perspective, having a table actively updating while the user is scrolling will disorient the user. The user will think they are in the top/middle/bottom of the table then suddenly find themselves in the bottom/top/middle. The user will think that they have viewed all the data in one section of the table but in reality the table will have added something they needed to see. For example, if the table is a list of alphabetized names, the user checks all names staring with "U", sees that there are none and then goes to check somewhere else in the table. Meanwhile, the table invisibly updates the "U" section with fresh names while the user is looking elsewhere. Even if the user understands that the table is dynamically updated (which most are not) they will have to continually scroll around checking virtually the entire table to see what has changed.
A better UI design is to give the user the ability to update. Put an "Update" or "New Data Available" button in the bar and then set it to appear when new data arrives. Upon clicking the button, freeze the table, update and only then let the user resume interaction. It would also be good design to visually flag the rows added.
This will make the UI more understandable for the user and solve your crashing problem at the same time.
Edit01:
If you don't use Core Data, in order to implement live and invisible updating of the table. you will need to freeze the in the calls – tableView:numberOfRowsInSection
or – numberOfSectionsInTableView:
before – tableView:cellForRowAtIndexPath:
is called.
Since – tableView:numberOfRowsInSection
is called first, I would put a call there to first update and then freeze your data model. That way the data model will return the proper number of sections and rows.
I presume you will have to divide you data model into two sections, one of which will buffer incoming data and another that will order the data for display. Your update method should move all the finalized buffered data into the display data section.
In addition, you will probably need to set a timer for when the user is not moving the table. The timer should call the update method if the table is not being actively manipulated and then it should force an update.
If you use Core Data, you can use NSFetchedResultController
and it's delegate methods will inform you when the data model changes. It should return the proper section and row information updated live. It's pretty easy to drive an updating table this way. However, it will not overcome the problem of data entering the model so quickly that the model changes between method calls. You will still have to freeze and/or slow down the model. You will however, not need the timer.
Core Data is your best option but even so it's going to be difficult to implement because you're trying to do something against the grain of the UI and therefore the API does not easily support it.