在UIViewControllers之间传递异步数据检索状态

时间:2014-01-21 18:12:48

标签: ios objective-c asynchronous uiviewcontroller

我正在做一些预取数据以减少等待时间的经验。在UIViewController A的viewDidLoad中,我从下载类启动一个异步函数来调用服务器来获取一些小块数据。下载程序类将此信息存储在某些Core Data表中。然后,当UIViewController B出现时,它使用该数据填充表。

当我在模拟器上运行它时,它毫无例外地工作。但是当我把它放在真正的手机上并从电脑上取下手机时,应用就崩溃了。当我到达VC B时,我点击一个按钮打开该表。该按钮单击将挂起,应用程序永远不会恢复。我检查了崩溃日志并得到了0x8badf00d错误。我正在测试旧的iPhone 4,这可能是我的问题的一部分,但应用程序需要在所有iPhone版本上运行,而不仅仅是新版本。

好的,所以我怀疑为什么会这样 - 数据还没有回来。作为一种快速而肮脏的测试方法,我输入了一个布尔用户默认值,我从VC A设置为NO。然后,当下载程序类获取数据时,它将同一个变量设置为YES。在viewDidLoad中的VC B中,我进入一个繁忙的循环使其等待,直到该值设置为YES。当我运行应用程序时,它立即清除了悬挂问题,并且VC B中的等待时间是即时的。用户永远不会知道这存在。

尽管取得了这种短暂的成功,但我认为我的这种方法很可怕!有没有比使用用户默认值更好的方法?我不知道如何在这里使用委托模式,通知也可能不起作用。我意识到我正在阻止UI线程,但这是故意的。在有可用数据之前,我无法让用户打开该表。是否有更优雅的方法更符合Objective C模式?

我可以发布代码,如果有帮助的话。谢谢!

2 个答案:

答案 0 :(得分:1)

我可能会收到类似这样的通知,并在后台进行下载(我无法判断你是否在后台进行下载)。

  1. 要在后台运行下载代码,请执行类似

    的操作

    [[DownloadManager instance] performSelectorInBackground:@ selector(doDownload)withObject:nil];

  2. 在doDownload类中完成后发布通知

    //Downloading code    
    ...    
    [[NSNotificationCenter defaultCenter] postNotificationName:@"DownloadsDidFinish" object:self]; 
    
  3. 在你的VC B中听取通知。

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadDidFinish :) name:@“DownloadsDidFinish”object:nil];

  4. 在downloadDidFinish中:您可能想要执行performSelectorOnMainThread,具体取决于您是否关心您是否在后台线程上。您也可以在发布通知时通过执行performSelectorOnMainThread在主线程上发布通知。

答案 1 :(得分:0)

您可以将ViewController B作为具有downloadedStarted和downloadedStopped方法的委托。您可以使用以下方法启动和停止旋转轮动画:

[busyIndicator startAnimating];