在[tableview reloadData]之前重新加载UITableViewController的模型

时间:2009-07-23 14:13:15

标签: objective-c iphone cocoa-touch uitableview

这是我第一次尝试iPhone开发,我有一些UITableViewController来显示从网络服务返回的数据。

在我的AppDelegate中,我设置了一个每隔几秒调用一次的计时器并重新加载模型。我保留相同的对象引用并刷新它的内容,因此我在目前可见的任何UITableViewController上都有相同的对象。

当在AppDelegate上刷新数据时,我调用:

[[(UITableViewController *)[self.navigationController topViewController] tableView] reloadData];

该模型基本上是file个对象的集合。每个file对象都有一些属性和标志。

如果当前UITableViewController是一个简单的表(包含一个部分),将每个单元格映射到files数组上的顺序索引,则此方法非常有效。

但我有UITableViewController之一显示此file详细信息,并且根据file对象上的标记,将显示2或3个部分。我把这个逻辑放在这里:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    if ([[_file status] intValue] & DOWNLOADING) {
        kIndexTransferSpeed = 1;
        kIndexSettings = 2;
        return 3;
    } else {
        kIndexSettings = 1;
        kIndexTransferSpeed = -1;
        return 2;   
    }
}

因此,在此控制器上,我的-tableView:cellForRowAtIndexPath:只是一个很大的if语句,它将显示_file对象的属性,具体取决于indexPath

这种方法的问题是当这个表在设备上重新加载时,我实际上可以看到它被重新加载。部分标题闪现片刻,细胞需要一些显示。特别是如果我在重新加载时滚动表。

我已经读到某个地方,我应该不让任何逻辑放在那些UITableViewController方法上。但我该怎么办?

我想过有一个特定的方法会创建一个“数据视图模型”,数据准备好被- tableView:cellForRowAtIndexPath:使用,并且在调用它的[tableView reloadData]之前会被AppDelegate调用。但是每次调用它时我都必须重新创建整个“视图模型”,因为它是同一个对象而我真的不知道数据模型上有什么变化。

1 个答案:

答案 0 :(得分:6)

reloadData必须处理很多事情,包括来来往往的部分,以相对顺序移动的对象等。如果不知道实际发生了什么,有时候除了基本上拆解和重建表之外没什么可做的。

如果您想避免这样做,您可以通知控制器已发生的特定更改。基本上,不是您的视图通过控制器中的dataSource重新加载所有数据,控制器会具体告诉它具体的日期和方式。

除了调用重新加载之外,还有很多工作,但它更高效,耗电更少,并且因为UI具有更好的信息,它不仅可以避免整个事物消失和重新出现,而且实际上可以在更改中动画。

您要查看的方法是:

- (void)beginUpdates;   // allow multiple insert/delete of rows and sections to be animated simultaneously. Nestable
- (void)endUpdates;     // only call insert/delete/reload calls inside an update block.  otherwise things like row count, etc. may be invalid.

- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;

- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;

有更多文档here