【发布时间】:2013-06-10 03:22:40
【问题描述】:
我正在使用 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];
});
[来源]Waiting until two async blocks are executed before starting another block
日志如下所示:
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!
(同样,hideSpinnerDownloadingMovies 方法在 fetchDataWithBlock 完成之前执行 - 我刚刚再次运行它,它看起来很像上面的日志,在“隐藏微调器...”之后添加了 2 个“电影添加!”)
以下是我阅读并尝试过的其他几页: (我希望我可以发布链接,但看来我需要 10 名声望才能这样做......显然,你没有得到这些链接 - 仅供参考,它们来自 fieryrobot.com 和其他一些 stackoverflow.com 页面)
我只是希望能够找到/保存内容,以使 UI 不会冻结(因此,在后台),并且只有在完成所有查找/保存操作后才能执行某些操作(显示基于操作等)。我不认为我要求太多?
我相信答案在于正确组合 Parse.com 的 API(阻塞或非阻塞)以及 Apple 的 Grand Central Dispatch。但这种神奇而神秘的组合让我难以捉摸。
底线:谁能提供一个代码示例,在执行另一段单独的代码之前执行所有 Parse.com 查找/保存操作?
这一定是可能的,否则你怎么可能向用户报告有关操作等的准确统计信息?其他人如何实现这一目标?
我已经束手无策了……
【问题讨论】:
-
必须在阅读开头后立即发表评论。不要放弃——一旦你解决了问题,它就会非常令人满意。编辑:在阅读时,您是否仔细查看了执行 dispatch_async 时代码的作用?在不完全了解发生了什么的情况下剪切和粘贴示例通常很危险,尤其是异步/事件驱动代码
-
感谢您的支持。 “fetchDataWithBlock”方法获取包含电影信息的 JSON 数据,然后遍历该数据 - 调用 Parse.com 的 PFQuery 对象的 API“findObjectsInBackgroundWithBlock”方法。在“findObjectsInBackgroundWithBlock”方法中,我可以检查是否有任何返回、错误等。这就是我提出问题的原因 - 我想等到对该方法的所有单独调用都完成,以便我可以评估所有结果一次(是否找到了所有电影,是否有错误等?)
-
您能解释一下
fetchDataWithBlock方法的性质吗?您是否可以访问此方法的代码? -
嘿用户...使用 Parse 做到这一点再简单不过了。你还需要答案吗?干杯!
标签: ios objective-c xcode objective-c-blocks