Search code examples
uitableviewnsoperationqueue

iOS, Delay Display in UITableView with insertRowsAtIndexPaths:withRowAnimation:


I have a custom NSObject class, doing some FTP work (display, transfer...).

This FTP class has a downloadFiles: method, which is launch inside a NSOperationQueue.

And I would like that method to provide some results as a data source in a UITableView. So I decided to delegate those results to the UITableViewController.

So the protocol for the FTP class :

@protocol FTPDelegate;

..

@interface FTP...    
@property (nonatomic, weak) id <FTPDelegate> delegate;

...

@protocol FTPDelegate
-(void)FTPMessageReceived: (NSString *)message;
@end

Then I declared the custom UITableViewController as delegate of the FTP class:

self.myFTP = (FTP *) [self FTPManager];

self.myFTP.delegate = self;

So when the downloadFiles: method from the FTP class wants to display some message in the UITableView, it calls:

[[self delegate] FTPMessageReceived:@"dir created"];

The UITableViewController implements that method :

-(void)FTPMessageReceived: (NSString *)message {
  NSUInteger index;
  NSArray * indexArray;
  [[self logLine] addObject: message]; // logLine is my data source
  index = [[self logLine] count]-1;
  NSLog(@"%u", index);
  indexArray = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:index inSection:0]];
  [[self logView] insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationRight];
}

The insert works, but the new row takes around 5 seconds to be displayed in the UITableView !!

And when I put some log inside the tableView:cellForRowAtIndexPath: method, it's display immediately.

And when I put the FTPMessageReceived code inside a button (for example), the UITableView displays the new row immediately !

Any suggestion?


Solution

  • It sounds like FTPMessageReceived: is being called on a background thread. Try calling it on the main thread with:

    dispatch_async(dispatch_get_main_queue(), ^{
        [[self delegate] FTPMessageReceived:@"dir created"];
    });