在我滚动之前,数据不会加载到UITableView中

Ben*_*men 53 cocoa objective-c synchronous uitableview

我试图在单元格中加载已解析的数据,但问题是它是同步发生的,UitableView在数据加载完成之前不会显示.我试图通过使用performSelectorInBackground解决问题,但现在数据没有加载到单元格中,直到我开始滚动.这是我的代码:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self performSelectorInBackground:@selector(fethchData) withObject:nil];


}


- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
self.listData = nil;
    self.plot=nil;
}


-(void) fethchData

{
    NSError *error = nil;
    NSURL *url=[[NSURL alloc] initWithString:@"http://www.website.com/"];
    NSString *strin=[[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];

    HTMLParser *parser = [[HTMLParser alloc] initWithString:strin error:&error];

    if (error) {
        NSLog(@"Error: %@", error);
        return;
    }

    listData =[[NSMutableArray alloc] init];
    plot=[[NSMutableArray alloc] init];

    HTMLNode *bodyNode = [parser body];
    NSArray *contentNodes = [bodyNode findChildTags:@"p"];


    for (HTMLNode *inputNode in contentNodes) {
            [plot addObject:[[inputNode allContents] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];    
        }


    NSArray *divNodes = [bodyNode findChildTags:@"h2"];

    for (HTMLNode *inputNode in divNodes) {

            [listData addObject:[[inputNode allContents] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];          

        }
    }


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{

    static NSString *CellIdentifier = @"Cell";
    //here you check for PreCreated cell.
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    }

    //Fill the cells...  


    cell.textLabel.text = [listData objectAtIndex:indexPath.row];
    cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
    cell.textLabel.numberOfLines=6; 
    cell.textLabel.textColor=[UIColor colorWithHue:0.7 saturation:1 brightness:0.4 alpha:1];


    cell.detailTextLabel.text=[plot objectAtIndex:indexPath.row];
    cell.detailTextLabel.font=[UIFont systemFontOfSize:11];
    cell.detailTextLabel.numberOfLines=6;

    return cell;


}
Run Code Online (Sandbox Code Playgroud)

Env*_*vil 129

数据加载成功后将其放在某处:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.tableView reloadData];
});
Run Code Online (Sandbox Code Playgroud)

这解决了当您不在主线程中时调用GUI更新的问题.

此代码使用Apple的GCD技术强制重载数据功能在主线程上运行.阅读更多关于 并发编程指南的内容以获得更多的理解(这是一个非常大的领域,因此很难在评论中解释)无论如何,如果你不理解它并不是很好,因为它会导致程序崩溃一些罕见的情况.


Ham*_*mid 14

对于swift 3:

DispatchQueue.main.async(execute: { () -> Void in
                self.tableView.reloadData()
            })
Run Code Online (Sandbox Code Playgroud)

对于swift 2:

dispatch_async(dispatch_get_main_queue(), { () -> Void in
                self.tableView.reloadData()
            })
Run Code Online (Sandbox Code Playgroud)


Dan*_*n F 9

您真正需要做的就是每次更新后端数据时都要打电话

[tableView reloadData];
Run Code Online (Sandbox Code Playgroud)

由于这是同步发生的,你应该有一个像这样的功能

-(void) updateTable
{
    [tableView reloadData];
}
Run Code Online (Sandbox Code Playgroud)

并在下载调用中添加数据后

[self performSelectorOnMainThread:@selector(updateTable) withObject:nil waitUntilDone:NO];
Run Code Online (Sandbox Code Playgroud)