Objective c 数据不存在';在我滚动之前,请不要在UITableView中加载

Objective c 数据不存在';在我滚动之前,请不要在UITableView中加载,objective-c,uitableview,cocoa,synchronous,Objective C,Uitableview,Cocoa,Synchronous,我试图在单元格中加载解析后的数据,但问题是它是同步发生的,直到数据加载完成,UitableView才会显示。我试图通过使用performSelectorInBackground来解决这个问题,但现在数据在我开始滚动之前不会加载到单元格中。这是我的密码: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.

我试图在单元格中加载解析后的数据,但问题是它是同步发生的,直到数据加载完成,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;


}

您真正需要做的就是在任何时候对后端数据进行更新时,致电

[tableView reloadData];
因为这是同步发生的,所以您可能应该有一个如下的函数

-(void) updateTable
{
    [tableView reloadData];
}
在下载通话中添加数据后

[self performSelectorOnMainThread:@selector(updateTable) withObject:nil waitUntilDone:NO];

成功加载数据后,将其放置在某个位置:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.tableView reloadData];
});
这解决了当您不在主线程中时调用GUI更新的问题。

此代码使用Apple的GCD技术强制重载数据函数在主线程上运行。阅读更多关于 更多了解(这是一个相当大的字段,因此很难在评论中解释)
无论如何,如果您不太了解它,就不太推荐它,因为它会导致程序在一些罕见的情况下崩溃。

我遇到了完全相同的问题!我希望在视图控制器出现之前完全填充UITableView。Envil的帖子给了我所需要的信息,但我的解决方案却不一样

以下是我所做的(重新建模以适应提问者的上下文)


您可以使用[cell setNeedsDisplay]; 例如:

dispatch_async(dispatch_get_main_queue(), ^{
            [cell setNeedsDisplay];
            [cell.contentView addSubview:yourView];
        });

我有这个问题,我整天都在处理它

我使用的是静态单元格,重新加载数据会导致错误加载,它只显示可见单元格,并删除其他单元格。 我注意到,当我向下滚动(y为负值)正确加载的单元格时,我编写了这段代码,它工作了,尽管我不喜欢这样

如果你找到更好的解决办法就开枪

-(void)reloadTableView{
        CGPoint point = self.tableSettings.tableView.contentOffset;
        [self.tableSettings.tableView reloadData];

        [UIView animateWithDuration:.001f animations:^{
            [self.tableSettings.tableView setContentOffset:CGPointMake(point.x, -10)];
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:.001f animations:^{
                [self.tableSettings.tableView setContentOffset:point];
            } completion:^(BOOL finished) {

            }];
        }];
}

对于swift 3:

DispatchQueue.main.async(execute: { () -> Void in
                self.tableView.reloadData()
            })
dispatch_async(dispatch_get_main_queue(), { () -> Void in
                self.tableView.reloadData()
            })
对于swift 2:

DispatchQueue.main.async(execute: { () -> Void in
                self.tableView.reloadData()
            })
dispatch_async(dispatch_get_main_queue(), { () -> Void in
                self.tableView.reloadData()
            })

首先,这个半成品解决了我的相关问题。我想在表格单元格中使图像的角变圆。异步调度修复了部分但不是所有映像的问题。有什么想法吗

其次,我认为您应该通过使用以下闭包捕获列表来避免创建强引用循环:

DispatchQueue.main.async(execute: { [weak weakSelf = self] () -> Void in
            weakSelf!.tableView.reloadData()
        })

请参阅:

我在使用自调整大小单元格时遇到了相同的问题,我发现将estimatedHeight设置为50可以解决此问题

在tableView本身上设置estimatedHeight,或从UITableViewDelegate中的
estimatedHeight for Rowat
返回估计值


只要估计值大于0,它似乎就可以工作。

仅加载可见单元格,滚动后显示的其余单元格将加载。它显示“未知接收器表视图”。该代码仅用于示例,我不知道您的类或视图布局的确切结构。关键是,您需要获得对表视图的引用(如果您的类是UITableViewController的实例或子类,那么您应该只拥有self.tableView)然后在UITabbleviewController中调用ITI上的
reloadData
方法。它将是self.tableView现在更好了,但我仍然需要触摸tableView以加载数据。以前,我必须滚动更多。无论如何,谢谢你们。我使用了这个[自执行选择器:@selector(fethchData)with object:nil afterDelay:0];结合您的示例代码。谢谢。我匆忙地移动了一些东西,并没有意识到我的数据加载在另一个线程中,因此我也重新加载了数据。谢谢你帮我回去分析,谢谢!这刚刚解决了我遇到的一个非常恼人的错误。@Envil你能解释一下它是如何导致崩溃的吗。我的应用程序正在随机崩溃。即使花了很多时间调试,我也无法修复崩溃。@AbdurrahmanMubeenAli你应该创建一个新问题,并对其进行详细描述。我不能用你的小描述给你一个解决方案。@Envil在你的回答中,你说,“……它导致程序崩溃……”。我只是想知道你知道的崩溃案例。这解决了我的问题:DispatchQueue.main.async(执行:{[weak-weakCell=cell]()->Void in-weakCell!.imageView!.layer.cornerRadius=cell.imageView!.frame.width/4.0 weakCell!.imageView!.clipsToBounds=true})这对我有效。如果你发现了真正的问题,请告诉我