我在 Xcode 4.6.2 中工作,试图开发一个 iPhone 应用程序。
在我的业余时间里,我已经断断续续地挣扎了好几个星期,我正考虑放弃开发,再也不会尝试创建移动应用程序。我对应该做的一件容易的事情感到非常沮丧......
我要做的就是:
- 使用 Parse.com 的 API “findObjects”/“findObjectsInBackgroundWithBlock”和“save”/“saveInBackgroundWithBlock”来获取和保存数据;接着
- 在所有此类操作完成后,再做一些事情(完全了解所有 Parse 操作的执行结果)。
例如,我想通过 for 循环将一些对象保存到 Parse,然后在将它们全部保存后,知道有多少成功、错误等,以便我可以在屏幕上显示这些数字。
另外例如,我想在 Parse.com 中查找对象做同样的事情,然后在我完成查找内容后,计算并显示找到了多少项目、多少重复项等(再次,在iPhone 屏幕)
为什么这么难?!
我尝试过使用大量的 Grand Central Dispatch 示例,例如“dispatch_async”和“dispatch_group_async”+“dispatch_group_notify”。我已经使用“WithBlock”Parse.com 方法以及非阻塞版本尝试了 GCD。
示例问题 #1:在从 Parse.com 检索所有项目之前隐藏微调器(我希望 hideSpinnerDownloadingMovies 方法 - 以及其中的任何其他内容 - 仅在 fetchDataWithBlock 和 fetchedDataWithBlock 内的所有 findObjectsInBackgroundWithBlock 完全完成后执行!)
[self showSpinnerDownloadingMovies];
dispatch_queue_t queue = dispatch_queue_create("com.app.task", NULL);
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_async(queue, ^{
[self fetchDataWithBlock];
dispatch_async(main, ^{
[self hideSpinnerDownloadingMovies];
});
});
[来源] http://cocoasamurai.blogspot.com/2009/09/guide-to-blocks-grand-central-dispatch.html
日志如下所示:
2013-06-09 18:17:09.159 TestApp[4425:4503] Epic
2013-06-09 18:17:09.160 TestApp[4425:4503] 104
2013-06-09 18:17:09.236 TestApp[4425:4503] Star Trek Into Darkness
2013-06-09 18:17:09.237 TestApp[4425:4503] 129
2013-06-09 18:17:09.341 TestApp[4425:c07] movie added!
2013-06-09 18:17:09.385 TestApp[4425:4503] Fast & Furious 6
2013-06-09 18:17:09.386 TestApp[4425:4503] 130
2013-06-09 18:17:09.484 TestApp[4425:c07] movie added!
2013-06-09 18:17:09.545 TestApp[4425:4503] After Earth
2013-06-09 18:17:09.545 TestApp[4425:c07] movie added!
2013-06-09 18:17:09.546 TestApp[4425:4503] 100
2013-06-09 18:17:09.634 TestApp[4425:4503] The Hangover Part III
2013-06-09 18:17:09.635 TestApp[4425:4503] 100
2013-06-09 18:17:09.636 TestApp[4425:c07] hiding spinner...
2013-06-09 18:17:09.742 TestApp[4425:c07] movie added!
2013-06-09 18:17:09.968 TestApp[4425:c07] movie added!
(看看在 fetchDataWithBlock 完成之前 hideSpinnerDownloadingMovies 方法是如何执行的?)
示例问题 #2:与上述相同,代码的顺序无法保证(hideSpinnerDownloadingMovies 等在 fetchDataWithBlock 中仍在查找/处理某些对象时执行)。
[self showSpinnerDownloadingMovies];
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self fetchDataWithBlock];
});
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self hideSpinnerDownloadingMovies];
});
日志如下所示:
2013-06-09 23:09:04.291 TestApp[4983:4903] Epic
2013-06-09 23:09:04.292 TestApp[4983:4903] 104
2013-06-09 23:09:04.365 TestApp[4983:4903] Star Trek Into Darkness
2013-06-09 23:09:04.366 TestApp[4983:4903] 129
2013-06-09 23:09:04.544 TestApp[4983:4903] Fast & Furious 6
2013-06-09 23:09:04.545 TestApp[4983:4903] 130
2013-06-09 23:09:04.696 TestApp[4983:4903] After Earth
2013-06-09 23:09:04.697 TestApp[4983:4903] 100
2013-06-09 23:09:04.797 TestApp[4983:4903] The Hangover Part III
2013-06-09 23:09:04.797 TestApp[4983:4903] 100
2013-06-09 23:09:04.798 TestApp[4983:4903] hiding spinner...
2013-06-09 23:09:05.049 TestApp[4983:c07] movie added!
2013-06-09 23:09:05.051 TestApp[4983:c07] movie added!
2013-06-09 23:09:05.053 TestApp[4983:c07] movie added!
2013-06-09 23:09:05.070 TestApp[4983:c07] movie added!
2013-06-09 23:09:05.287 TestApp[4983:c07] movie added!
(同样,在 fetchDataWithBlock 完成之前,hideSpinnerDownloadingMovies 方法正在执行 - 我刚刚再次运行它,它看起来很像上面的日志,在“隐藏微调器...”之后添加了 2 个“电影添加!”)
以下是我阅读并尝试过的其他一些页面:(我希望我可以发布链接,但看来我需要 10 名声望才能这样做......显然,你没有得到这些链接 - 仅供参考,它们来自fieryrobot.com 和其他一些 stackoverflow.com 页面)
我只想能够找到/保存东西,这样 UI 就不会冻结(所以,在后台),并且只有在所有查找/保存操作完成后才能做一些事情(根据操作显示统计信息, ETC。)。我不觉得我要求太多了?
我相信答案在于正确组合 Parse.com 的 API(阻塞或非阻塞)以及 Apple 的 Grand Central Dispatch。但这种神奇而神秘的组合让我望而却步。
底线:任何人都可以提供在执行另一段单独的代码之前执行所有 Parse.com 查找/保存操作的代码示例吗?
这必须是可能的,否则你怎么能将有关操作等的准确统计数据报告给用户?其他人如何实现这一目标?
我脑洞大开……