如何在同步后正确处理UI刷新

时间:2012-09-17 14:33:29

标签: objective-c ios cocoa-touch grand-central-dispatch

我有一个应用程序,可以在每次启动时使用Rails后端与服务器同步数据。 API完全有效,但是当界面需要刷新时,我遇到了界面变得无法响应的问题。

我目前正在使用GCD启动同步:

Sync *sync = [[Sync alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [sync force_sync:@""];
    [appModel updateSyncTime:current_time];
});

同步完成后,我让Sync对象向应用程序发送NSNotification,以便界面刷新:

dispatch_async(dispatch_get_main_queue(), ^{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"Sync-Completed" object:self];
});

当收到通知时,我的其他类只是简单地在UITableView中重新加载数据,如下所示:

 - (void)notificationReceived:(NSNotification *)notification {
    [dataTable reloadData];
 }

在收到通知之前,UI完全响应。收到通知后,您无法在刷新完成之前滚动其他UI元素中的UITableViews。我确定有更好的方法可以做到这一点,但是怎么做?

提前致谢!

1 个答案:

答案 0 :(得分:1)

dispatch_async(dispatch_get_main_queue(), ^{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"Sync-Completed" object:self];
});

不是异步 - 您只是在主队列上卸载了大量的刷新工作(同步完成通知的处理) - 所以除非您解决更新UI的代码,否则您的应用将会锁定。 / p>

此外,使用全局队列进行繁重的IO操作不一定是个好主意。我已经看到只是这样做会锁定UI的情况 - 所以确保它的通知而不是同步本身。

如果你发现它是同步本身 - 创建你自己的NSOperation队列并从该块中创建一个NSOperation。

您的里程可能会有所不同,但一般情况下使用全局队列对我来说不适用于异步IO。