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

leo*_*ato 3 iphone cocoa-touch objective-c uitableview

这是我第一次尝试iPhone开发,我有一些UITableViewController将显示从Web服务返回的数据.

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

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

[[(UITableViewController *)[self.navigationController topViewController] tableView] reloadData];
Run Code Online (Sandbox Code Playgroud)

该模型基本上是一组file对象.每个file对象都有一些属性和标志.

如果当前UITableViewController是一个简单的表,其中一个部分将每个单元格映射到Array的顺序索引,则此方法非常有效files.

但我有一个UITableViewController显示此file细节的s,并根据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;   
    }
}
Run Code Online (Sandbox Code Playgroud)

所以在这个控制器上,我-tableView:cellForRowAtIndexPath:只是一个很大的if声明,它将显示来自_file对象的属性,具体取决于indexPath.

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

我已经读到某个地方,我应该让自己不要对这些UITableViewController方法施加任何逻辑.但是我该怎么办?

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

Lou*_*arg 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;
Run Code Online (Sandbox Code Playgroud)

这里有更多文档.