[UITableView reloadData]是什么意思?

22
我有一个应用程序,其中包含一个UITableView。这个UITableView是由在appDelegate中作为属性持有的NSMutableArray填充的。你可以把它看做是一个邮件窗口。它列出了一些子类化的UITableViewCell中的消息。当出现新消息时,我已经完成了所有代码,它会下载消息,将数据添加到appDelegate的NSMutableArray中,该数组保存所有消息。这段代码运行良好。
现在,一旦新信息被下载并添加到数组中,我尝试使用以下代码更新我的UITableView,但是UITableView的委托方法没有被调用。
奇怪的是,当我上下滚动UITableView时,委托方法最终被调用,并且我的区域标题确实更改了(它们显示该部分的消息计数)。它们不应该实时更新而不是等待我的滚动来触发刷新吗?此外,新单元格也从未添加到区域中!
请帮忙!!
APPDELEGATE CODE:
[self refreshMessagesDisplay]; //This is a call placed in the msg download method

-(void)refreshMessagesDisplay{
    [self performSelectorOnMainThread:@selector(performMessageDisplay) withObject:nil waitUntilDone:NO];
}

-(void)performMessageDisplay{
    [myMessagesView refresh];
}

UITableViewController 代码:

-(void) refresh{
    iPhone_PNPAppDelegate *mainDelegate = (iPhone_PNPAppDelegate *)[[UIApplication sharedApplication] delegate];

    //self.messages is copied from appDelegate to get (old and) new messages.
    self.messages=mainDelegate.messages;

    //Some array manipulation takes place here.

    [theTable reloadData];
    [theTable setNeedsLayout];  //added out of desperation
    [theTable setNeedsDisplay];  //added out of desperation
}

2
兄弟,我感同身受,我也遇到了同样的问题。 - Di Wu
4个回答

29

作为一个合理性检查,你是否在那个时间点验证过theTable不是nil?


7
0x0 实际上是 nil——表视图当然存在,但你指向它的指针没有被正确设置。请仔细检查你的 nib。 (注:nib 是一种使用 Interface Builder 创建用户界面的文件类型,用于 iOS 和 macOS 应用程序开发) - Marc Charbonneau
那肯定是问题所在。由于某种原因(没有看到所有代码无法确定),你的“theTable”变量为nil,因此reloadData消息无法传递。 - smorgan
4
为什么不使用self.tableView而是维护对表的单独引用? - dmercredi
9
因为我不是自己的英雄,就像你现在是我的英雄一样。我还有很多要学习的!谢谢大家! - Dutchie432
+1 用于检查它不是 nil。很奇怪,即使控制器没有正确指向表,表仍然能够正常工作。 - Rafael Vega
显示剩余2条评论

12
你可以尝试在reloadData调用中加入延迟 - 当我尝试重新排列单元格并更新tableview时,我曾遇到类似的问题,但如果在其中调用reloadData,则应用程序会崩溃。所以这样做可能值得一试:
像这样的刷新方法:
    - (void)refreshDisplay:(UITableView *)tableView {
    [tableView reloadData]; 
}

然后通过(比如说)0.5秒的延迟来调用它:

[self performSelector:(@selector(refreshDisplay:)) withObject:(tableView) afterDelay:0.5];

希望它能够正常工作...


这也是我的问题。我正在从 NSNotificationCenter 通知选择器中重新加载数据。 - NathanAldenSr
+1 真是惊人!不知道为什么,但我还是需要这样做。 - Peter K.

6
如果您在调用reloadData时使用了分派方法,请确保在主队列上执行它。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0), ^(void) {

    // hard work/updating here

    // when finished ...
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        [self.myTableView reloadData];
    }); 
});

..与方法形式相同:

-(void)updateDataInBackground {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0), ^(void) {

        // hard work/updating here

        // when finished ...
        [self reloadTable];
    });
}

-(void)reloadTable {
       dispatch_async(dispatch_get_main_queue(), ^(void) {
            [myTableView reloadData];
        }); 
}

1
太好了!我正在后台线程中进行更新,但实际上什么都没做。谢谢。 - nont

0
你尝试在刷新方法中设置断点,以确保在调用reloadData之前,你的消息数组具有正确的内容了吗?

是的。那个方法已经被多次审核过了。我可以看到我的数组计数增加,甚至可以在调试器中看到我的新对象(消息)以及所有适当的值。 - Dutchie432

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接