Is -[Uitableview Reloaddata] Asynchronous or Synchronous

Is -[UITableView reloadData] asynchronous or synchronous?

This method actually just removes all the UITableViewCell views from the table. The data source delegate methods are called when the table is repainted.

So, it's asynchronous.

Edit:

Actually, some calls ARE synchronous. The number of sections & rows and row heights are updated immediately, so, for example contentSize is set correctly after the call. On the other hand, tableView:cellForRowAtIndex: is not called until the table is repainted.

UITableView reloadData asynchronous

You shouldn't be releasing a global there. Use a synthesized property with retain semantics and release in the view controller's dealloc method.

Edit:

Use dispatch_async() instead of dispatch_sync() in your call back to the main thread. dispatch_sync() will block the global background queue while the main thread finishes updating the tableview.

How to reloadData for tableview after data been prepared in a asynchronously method

You should never access any UI from background threads, you must do it from the main thread, to do this you may use gcd:

DispatchQueue.main.async {
self.tableView.reloadData()
}

While accessing UI (read everything UIKit) from background thread may work sometimes, you'll end up with bugs including crashes, blown up display or gazenbugs.

Call function only after reloadData has finished

The problem is that you call reloadData immediately after starting the URL request. That does not make sense because the request has not been completed at that point.

The correct way would be to call reloadData and methodB in connectionDidFinishLoading, after you have updated your data source with the response from the URL request. At that point you know if the number of rows is zero or not, and there is no need to wait for the table view update to complete.

How can I tell when UITableView has completed ReloadData?

The reload happens during the next layout pass, which normally happens when you return control to the run loop (after, say, your button action or whatever returns).

So one way to run something after the table view reloads is simply to force the table view to perform layout immediately:

[self.tableView reloadData];
[self.tableView layoutIfNeeded];
NSIndexPath* indexPath = [NSIndexPath indexPathForRow: ([self.tableView numberOfRowsInSection:([self.tableView numberOfSections]-1)]-1) inSection: ([self.tableView numberOfSections]-1)];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

Another way is to schedule your after-layout code to run later using dispatch_async:

[self.tableView reloadData];

dispatch_async(dispatch_get_main_queue(), ^{
NSIndexPath* indexPath = [NSIndexPath indexPathForRow: ([self.tableView numberOfRowsInSection:([self.tableView numberOfSections]-1)]-1) inSection:([self.tableView numberOfSections]-1)];

[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
});

UPDATE

Upon further investigation, I find that the table view sends tableView:numberOfSections: and tableView:numberOfRowsInSection: to its data source before returning from reloadData. If the delegate implements tableView:heightForRowAtIndexPath:, the table view also sends that (for each row) before returning from reloadData.

However, the table view does not send tableView:cellForRowAtIndexPath: or tableView:headerViewForSection until the layout phase, which happens by default when you return control to the run loop.

I also find that in a tiny test program, the code in your question properly scrolls to the bottom of the table view, without me doing anything special (like sending layoutIfNeeded or using dispatch_async).



Related Topics



Leave a reply



Submit