如何确保在正确的时间调用通知

时间:2012-10-28 18:05:43

标签: objective-c multithreading grand-central-dispatch

我有一个场景,我必须迭代一个帐号列表,去获取这些帐户的详细信息,然后将汇总的信息传递给completionBlock。为了方便这一点,我使用了dispatch_group_ *方法。不幸的是,即使我已明确调用

,完成块在小组完成之前被称为

dispatch_group_wait(_imfDispatchGroup, DISPATCH_TIME_FOREVER);

控制台日志示例(原始):

  

2012-10-28 13:58:46.722 ThreadingHell [81909:303]在loginResponse内

     

2012-10-28 13:58:46.724 ThreadingHell [81909:303]内部帐户循环   对于obj:account1

     

2012-10-28 13:58:46.724 ThreadingHell [81909:303]内部帐户循环   对于obj:account2

     

2012-10-28 13:58:46.724 ThreadingHell [81909:1b03]内幕细节:   L0i6kRVzGG详细信息

     

2012-10-28 13:58:46.724 ThreadingHell [81909:1a03]内幕细节:   SE0QjhO8Hh详细信息

     

2012-10-28 13:58:46.724 ThreadingHell [81909:303]内部帐户循环   对于obj:account3

     

2012-10-28 13:58:46.725 ThreadingHell [81909:1a03]内部完成   for __66- [ModelManager   getAccountDetailsForAccountNumber:completionBlock:] _ block_invoke_015

     

2012-10-28 13:58:46.725 ThreadingHell [81909:1803]内幕细节:   9SsGYOX3u5详细信息

     

2012-10-28 13:58:46.725 ThreadingHell [81909:1a03]详细资料被发现   帐户

     

2012-10-28 13:58:46.725 ThreadingHell [81909:303]内部帐户循环   对于obj:account4

     

2012-10-28 13:58:46.725 ThreadingHell [81909:1b03]内部完成   for __66- [ModelManager   getAccountDetailsForAccountNumber:completionBlock:] _ block_invoke_015

     

2012-10-28 13:58:46.726 ThreadingHell [81909:1803]内部完成   for __66- [ModelManager   getAccountDetailsForAccountNumber:completionBlock:] _ block_invoke_015

     

2012-10-28 13:58:46.726 ThreadingHell [81909:303]内部帐户循环   对于obj:acount5

     

2012-10-28 13:58:46.726 ThreadingHell [81909:1a03]成功账号   德路

     

2012-10-28 13:58:46.726 ThreadingHell [81909:1b03]详细信息   帐户

     

2012-10-28 13:58:46.726 ThreadingHell [81909:2303]内幕细节:   wSXis5bIVs详细信息

     

2012-10-28 13:58:46.728 ThreadingHell [81909:1803]详细资料被发现   帐户

     

2012-10-28 13:58:46.728 ThreadingHell [81909:2403]内幕细节:   SrIfbzBLr7详细信息

     

2012-10-28 13:58:46.728 ThreadingHell [81909:1a03]当前的实例   帐户详细资料: (       " L0i6kRVzGG详情" )

     

2012-10-28 13:58:46.728 ThreadingHell [81909:1803]成功账号   德路

     

2012-10-28 13:58:46.728 ThreadingHell [81909:1b03]成功账号   德路

     

2012-10-28 13:58:46.729 ThreadingHell [81909:2403]内部完成   for __66- [ModelManager   getAccountDetailsForAccountNumber:completionBlock:] _ block_invoke_015

     

2012-10-28 13:58:46.729 ThreadingHell [81909:303] !!!!!!!!!!即将到来   呼叫完成块。这应该是最后一次

     

2012-10-28 13:58:46.729 ThreadingHell [81909:2303]内部完成   for __66- [ModelManager   getAccountDetailsForAccountNumber:completionBlock:] _ block_invoke_015

     

2012-10-28 13:58:46.730 ThreadingHell [81909:1803]当前的实例   帐户详细资料: (       " L0i6kRVzGG详细信息",       " 9SsGYOX3u5详情" )

     

2012-10-28 13:58:46.730 ThreadingHell [81909:1b03]当前的实例   帐户详细资料: (       " L0i6kRVzGG详细信息",       " 9SsGYOX3u5详细信息",       " SE0QjhO8Hh详情" )

     

2012-10-28 13:58:46.731 ThreadingHell [81909:2403]详细信息被发现   帐户

     

2012-10-28 13:58:46.731 ThreadingHell [81909:2303]详细信息被发现   帐户

     

2012-10-28 13:58:46.732 ThreadingHell [81909:2403]成功账号   德路

     

2012-10-28 13:58:46.731 ThreadingHell [81909:303] obj:{}

     

2012-10-28 13:58:46.732 ThreadingHell [81909:2303]成功账号   德路

     

2012-10-28 13:58:46.732 ThreadingHell [81909:303]错误:(null)

     

2012-10-28 13:58:46.732 ThreadingHell [81909:2403]当前的实例   帐户详细资料: (       " L0i6kRVzGG详细信息",       " 9SsGYOX3u5详细信息",       " SE0QjhO8Hh详细信息",       " wSXis5bIVs详情" )

//来自最新提交的更新日志[https://github.com/kwylez/ThreadingHell/tree/80cc29fab142b4dc1f386df747c5142b28e2dd84]

  

2012-10-28 16:32:38.984 ThreadingHell [83171:303]在loginResponse中   2012-10-28 16:32:38.987 ThreadingHell [83171:303]内部帐户循环   for obj:account1 2012-10-28 16:32:38.987 ThreadingHell [83171:303]   obj的内部帐户循环:account2 2012-10-28 16:32:38.987   ThreadingHell [83171:1b03]内幕细节:CP3ioYdvXp详情   2012-10-28 16:32:38.987 ThreadingHell [83171:303]内部帐户循环   for obj:account3 2012-10-28 16:32:38.987 ThreadingHell [83171:1a03]   内幕细节:6k635XoJOV详情2012-10-28 16:32:38.987   ThreadingHell [83171:1b03]内部完成__66- [ModelManager   getAccountDetailsForAccountNumber:completionBlock:] _ block_invoke_0   2012-10-28 16:32:38.988 ThreadingHell [83171:1a03]内部完成   for __66- [ModelManager   getAccountDetailsForAccountNumber:completionBlock:] _ block_invoke_0   2012-10-28 16:32:38.988 ThreadingHell [83171:1b03]详细信息   for account 2012-10-28 16:32:38.988 ThreadingHell [83171:303]里面   对象的帐户循环:account4 2012-10-28 16:32:38.988   ThreadingHell [83171:1803]内幕细节:2TjGF1fdaZ详情   2012-10-28 16:32:38.989 ThreadingHell [83171:1a03]详细资料被发现   for account 2012-10-28 16:32:38.990 ThreadingHell [83171:1b03]成功   account looop 2012-10-28 16:32:38.991 ThreadingHell [83171:1b03]   accountDetails的当前实例:(       " CP3ioYdvXp详情" )2012-10-28 16:32:38.990 ThreadingHell [83171:303]内部帐户循环为obj:acount5   2012-10-28 16:32:38.990 ThreadingHell [83171:2303]内幕细节:   0YiuX9gHsu详情2012-10-28 16:32:38.990 ThreadingHell [83171:1a03]   成功账户looop 2012-10-28 16:32:38.990   ThreadingHell [83171:1803]完成__66- [ModelManager   getAccountDetailsForAccountNumber:completionBlock:] _ block_invoke_0   2012-10-28 16:32:38.992 ThreadingHell [83171:2303]内部完成   for __66- [ModelManager   getAccountDetailsForAccountNumber:completionBlock:] _ block_invoke_0   2012-10-28 16:32:38.992 ThreadingHell [83171:1b03]内幕细节:   9RcyOfjRa5详细信息2012-10-28 16:32:38.992 ThreadingHell [83171:1a03]   accountDetails的当前实例:(       " CP3ioYdvXp详情",       " 6k635XoJOV详情" )2012-10-28 16:32:38.992 ThreadingHell [83171:1803]详细资料找到账号2012-10-28   16:32:39.005 ThreadingHell [83171:1803]成功账号   2012-10-28 16:32:39.005 ThreadingHell [83171:1b03]内部完成   for __66- [ModelManager   getAccountDetailsForAccountNumber:completionBlock:] _ block_invoke_0   2012-10-28 16:32:39.005 ThreadingHell [83171:2303]详细资料被发现   for account 2012-10-28 16:32:39.006 ThreadingHell [83171:1b03]详情   找到的帐户2012-10-28 16:32:39.006   ThreadingHell [83171:2303]成功账号looop 2012-10-28   16:32:39.006 ThreadingHell [83171:1803]当前的实例   帐户详细资料: (       " CP3ioYdvXp详情",       " 6k635XoJOV详细信息",       " 2TjGF1fdaZ详情" )2012-10-28 16:32:39.007 ThreadingHell [83171:1b03]成功账号looop 2012-10-28   16:32:39.007 ThreadingHell [83171:2303]当前的实例   帐户详细资料: (       " CP3ioYdvXp详情",       " 6k635XoJOV详细信息",       " 2TjGF1fdaZ详情",       " 0YiuX9gHsu详情" )2012-10-28 16:32:39.008 ThreadingHell [83171:1b03] accountDetails的当前实例:(       " CP3ioYdvXp详情",       " 6k635XoJOV详细信息",       " 2TjGF1fdaZ详情",       " 0YiuX9gHsu详情",       " 9RcyOfjRa5详情" )2012-10-28 16:32:39.008 ThreadingHell [83171:303] !!!!!!!!!!即将调用完成块。   这应该是2012-10-28 16:32:39.009 ThreadingHell [83171:303]   obj:{} 2012-10-28 16:32:39.009 ThreadingHell [83171:303]错误:   (空)

什么"操作顺序"我错过了吗?

这是github上的示例项目的链接(代码太多了,不能放在这里):

https://github.com/kwylez/ThreadingHell

2 个答案:

答案 0 :(得分:0)

(我还没下载你的项目,在我的手机上回答,道歉......)

请改用NSOperationQueue。将每个操作添加为完成操作的依赖项。

这是一个更清洁,更像可可的API。您不必进行太多更改,因为您可以使用NSBlockOperation并传入您当前用于GCD的相同块。

答案 1 :(得分:0)

最新代码commit

解决了我上次发表评论的问题,我的问题得到了解答......使用dispatch_group方法。

getAccountDetailsForAccountNumber:completionBlock方法中,我删除了对dispatch_group_notify的调用,并在dispatch_group_async方法中移动了“完成”块登录。这解决了这个问题,因为完成块现在是队列任务的一部分而getAccountListMetaInformation:必须“服从”dispatch_group_wait命令,而不是之后通知会收到并发通知