3

背景:该应用程序的基本思想是以类似于 Snapchat 的方式向朋友发送内容。该应用程序已经可以运行,但现在我正在尝试一些性能改进。现在,在生成内容的屏幕上选择“下一步”按钮后,会出现延迟,因为被推送的视图控制器必须加载大约 30 个单元格的 UITableView。这是我之前加速过渡的尝试:

- (void)viewDidLoad
{
     [super viewDidLoad];
     // Do any additional setup after loading the view from its nib.
     self.selectFriendsViewController = [[MPOSelectFriendsViewController alloc]
                                        initWithNibName:@"MPOSelectFriendsViewController"
                                        bundle:nil];
     [self.selectFriendsViewController awakeFromNib]; 
}

当按下下一个按钮时:

- (void)gotoFriendsPage {
    [self.navigationController pushViewController:self.selectFriendsViewController animated:YES];
}

我想要做什么: Snapchat 不知何故总是以零延迟预加载朋友的列表,如下所示:

http://i.stack.imgur.com/FPMI5.jpg

显然,他们使用 UIPageViewController 而不是 UINavigationController 来实现这种效果,但我的问题实际上是这些:

1.如果我将我的后备控制器从 UINavigationController 更改为 UIPageViewController,这种零延迟加载会是自动的吗?

2.有没有办法通过 UINavigationController 获得像这样的零延迟加载时间?

在此先感谢您的帮助!

编辑:请求我的表格视图 cellForRowAtIndexPathCode:

 static NSString *cellIdentifier = @"FriendSelectionCell";

    MPOFriendSelectionCell *cell = (MPOFriendSelectionCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil) {
         cell = [[MPOFriendSelectionCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
     }
     MPOUser *friend = [self.friendManager.recentFriends objectAtIndex:indexPath.row];

     if(friend != (MPOUser *)[NSNull null]) {
         cell.currentFriend = friend;
         cell.friendLabel.text = friend.fullName;
     }
     return cell;
4

2 回答 2

3

对此没有单步解决方案。您需要实现缓存,并在加载时立即在 UI 上显示该信息。有很多方法可以缓存数据。您可以使用 NSUserDefaults(我不建议将其用于大数据)或许多其他缓存方法。之后,您需要延迟加载所有新信息,并找出一种智能方法来更新已表示数据的单元格的信息,并为 UITableView 中尚未表示的新数据插入新行。

与您的情况相关的电话将是:

  1. [UITableView reloadRowsAtIndexPaths: withRowAnimation:]
  2. [UITableView insertRowsAtIndexPaths: withRowAnimation:]
  3. [UITableView deleteRowsAtIndexPaths: withRowAnimation:]

上述方法接受一个索引路径数组和一个 UITableViewRowAnimation。对于索引路径,您可以执行类似的操作[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:0 inSection:0], [NSIndexPath indexPathForRow:1 inSection:0], /*and so on*/ nil];

我建议使用 aUITableViewRowAnimationFade来重新加载行,和UITableViewRowAnimationTop/UITableViewRowAnimationBottom来插入或删除行。

当您最初加载视图控制器时,使用缓存信息来呈现单元格。在您的 viewDidLoad 中,产生一个下载/加载新数据的后台调用,一旦完成,立即更新您的 UITableView。

这里唯一的缺点是在第一次加载时,没有数据可以显示。您可以通过加载一些默认或占位符数据来绕过这一点,以便用户在加载实际数据时可以玩一些东西。

很抱歉,我可以在这里发布的代码不多。您的问题没有一个包罗万象的解决方案,有多种方法可以解决这个问题。我的回答是最好的方法,但我相信还有很多其他方法可以解决这个问题。

此外,在仪器中运行时间分析器......它将帮助您查看应用程序的哪个部分消耗的时间最多。

于 2013-07-09T18:07:26.227 回答
2

我在这种情况下(我从外部源获取数据)采用的方法是将Array用于TableView数据源的数据保存到NSUserDefaults,然后在viewDidLoad触发时首先加载它。之后,我调用我的网络服务来获取新数据并将Array加载的数据与我从网络服务获得NSUserDefaults的刚刚下载的数据进行比较。Array如果他们是平等的,什么也不做。如果它们不同,请更新TableView并将最新数据保存回NSUserDefaults.

即使对于大型数据集(8000 条记录),这也能快速有效地工作。

于 2013-07-09T18:17:58.797 回答