I am struggling with a UITableView that I previously had working and somehow I have broken it!
It is part of a unit in Paul Hegarty’s course
The symptom is that the view loads but it is empty. I am clearly misunderstanding something fairly basic.
So far as I understand the two key methods are 1 the section rows count which in my case is returning zero, which I know is wrong!
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// #warning Incomplete method implementation.
// Return the number of rows in the section.
NSLog(@"TopPlaces %@",self.topPlaces);
//return 100;
return [self.topPlaces count];
}
Because of the above the following method is never called because there are no rows.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
And the second is within ViewDidLoad where I can log my data to the console and everything appears fine. i.e. my data is generated within ViewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_queue_t dowloadQueue = dispatch_queue_create("flick downloader", NULL);
dispatch_async(dowloadQueue, ^{
NSArray *topPlaces = [FlickrFetcher topPlaces];
//NSLog(@"Array is %@",topPlaces); // array is OK here
dispatch_async(dispatch_get_main_queue(), ^{
NSSortDescriptor *woeDescriptor = [[NSSortDescriptor alloc] initWithKey:@"_content" ascending:YES];
NSArray *woeDescriptors = @[woeDescriptor];
NSArray *sortedReturns = [topPlaces sortedArrayUsingDescriptors:woeDescriptors];
self.topPlaces = sortedReturns;
//all the data is present here, count is 100 and array will log to console
NSLog(@"count here is %u",[self.topPlaces count]);
});
});
// Uncomment the following line to preserve selection between presentations.
self.clearsSelectionOnViewWillAppear = NO;
}
The problem is that you make an asynchronous call to fetch the data (which means that your array should be full of data at some point in the future), but you do not reload your tableview afterwards. Calling
reloadDatawill do the trick:This will instruct your tableview to query once again its datasource and will eventually load all the data in your (now non-empty)
topPlacesarray.Further Explanation:
I saw in the comment of @nerak99 that he is not completely sure why the problem fixed with
reloadData.Well, let’s use an example:
Imagine that you’ve got a restaurant.
You open the place at 06:00 in the morning and you see that you’ve got nothing to cook. So you ask from one of your guys to go to the market for supplies (that’s your asynchronous call).
At the same time you instruct a waitress to write today’s menu, so she writes… well, nothing (that’s your tableview asking for number of rows).
Now at 07:00 the guy who went to the market returns with 10 items. What is the next logical step in order to update your menu? To actually inform the waitress (that’s your
reloadData) about the items you’ve returned with.I hope that this makes sense 🙂