I will fetch data from a web server, parse it, and display information in the table.
Code looks like the following (before):
-(void)fetchAndParse
{
// Fetch and Parse
[[NSNotificationCenter defaultCenter] postNotificationName:kDataRetrieved object:nil userInfo:userInfo];
}
- (void)dataRetrivalSucceeded:(NSNotification *)notification
{
// Save data
[myTable reloadData];
}
It was working fine until I decided to put parsing into a separate thread (using NSOperation), data sometimes shows up and sometimes doesn't. The UITableView will load data as usual, or remain blank until I drag it.
Code after:
-(void)fetch
{
// Fetch
queue = [NSOperationQueue new];
NSInvocationOperation *summaryOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(parseXml:) object:data];
[queue addOperation:parseOperation];
[summaryOperation release];
}
-(void)parseXml
{
// Parse
[[NSNotificationCenter defaultCenter] postNotificationName:kDataRetrieved object:nil userInfo:userInfo];
}
- (void)dataRetrivalSucceeded:(NSNotification *)notification
{
// Save data
[myTable reloadData];
}
And that's when I found out the notification is delivered in the thread in which the notification was posted (Link).
In a multithreaded application, notifications are always delivered in the thread in which the notification was posted, which may not be the same thread in which an observer registered itself.So what I did to make it work is the following:
-(void)fetch
{
// Fetch
queue = [NSOperationQueue new];
NSInvocationOperation *summaryOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(parseXml:) object:data];
[queue addOperation:parseOperation];
[summaryOperation release];
}
-(void)parseXml
{
// Parse
[[NSNotificationCenter defaultCenter] postNotificationName:kDataRetrieved object:nil userInfo:userInfo];
}
- (void)dataRetrivalSucceeded:(NSNotification *)notification
{
[self performSelectorOnMainThread:@selector(updateTable:) withObject:notification waitUntilDone:NO];
}
- (void)updateTable:(NSNotification *)notification
{
// Save data
[myTable reloadData];
}
The reason data shows after I dragged it is because it calls [myTable reloadData]; on main thread, while I wasn't.
The reason data shows after I dragged it is because it calls [myTable reloadData]; on main thread, while I wasn't.

