现在,当嵌套循环的多个服务器调用方法全部完成时,如何知道

时间:2013-03-09 04:01:42

标签: ios objective-c objective-c-blocks grand-central-dispatch

我有多个方法,每个方法都有嵌套循环和facebook请求。有一个X id的数组,每个方法循环遍历每个id,请求该id然后用结果数据填充。

我需要在每个方法完成时得到通知...即,当方法完成循环遍历数组中的所有id时,为每个方法生成facebook请求,收到结果并用结果数据完成任务。我似乎无法弄清楚如何实现这一目标。以下是方法的示例:

- (void)runLoopForFacebookFriendsContent1 {

    for (NSString *fbIdStr in self.fbIdsArr){
        FBRequest *fbRequest = [FBRequest requestWithGraphPath:graphPathString parameters:nil HTTPMethod:@"GET"];
        [fbRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
            if (error) {
                //show alert
            } else {
                //Do stuff with the resulting data
            }
        }];
    }    
}

- (void)runLoopForFacebookFriendsContent2 {

    for (NSString *fbIdStr in self.fbIdsArr){
        FBRequest *fbRequest2 = [FBRequest requestWithGraphPath:graphPathStringNumber2 parameters:nil HTTPMethod:@"GET"];
        [fbRequest2 startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
            if (error) {
                //show alert
            } else {
                for (PF_FBGraphObject *obj in [result objectForKey:@"data"]){
                    NSLog(@"facebook result:  %@",result);
                        NSMutableDictionary *dict          = [[NSMutableDictionary alloc]init];
                        [dict setValue:@"type2" forKey:@"ContentType"];
                        [dict setValue:obj forKey:@"data"];
                        [self.theFacebookDataArray addObject:dict];
                }
            }
        }];
    }    
}

我在viewWillAppear中调用这些方法。有没有办法设置某种完成处理程序来调用这些方法?什么时候完成后发布NSNotification?

3 个答案:

答案 0 :(得分:1)

一种选择是查看ReactiveCocoa框架。在你经历了一些学习曲线之后,我发现它对这种模式有很大的帮助。

以下是直接来自链接文件的示例:

// Perform 2 network operations and log a message to the console when they are
// both completed.
//
// +merge: takes an array of signals and returns a new RACSignal that passes
// through the values of all of the signals and completes when all of the
// signals complete.
//
// -subscribeCompleted: will execute the block when the signal completes.
[[RACSignal 
    merge:@[ [client fetchUserRepos], [client fetchOrgRepos] ]] 
    subscribeCompleted:^{
        NSLog(@"They're both done!");
    }];

您可以非常轻松地将其改编为Facebook SDK。

答案 1 :(得分:1)

此行为是预期的,因为您正在调用dispatch_group_enter,然后立即调用dispatch_group_leave,这意味着该组无需等待。

您应该在每个块之前调用dispatch_group_enter,并在每个块结束时调用dispatch_group_leave

检查接受的答案: Wait until multiple networking requests have all executed - including their completion blocks

<强>更新 对于给定的示例,您可以在每次调用dispatch_group_enter之前致电startWithCompletionHandler:,并在完成功能块结束时调用dispatch_group_leave

for (...) {
    FBRequest *fbRequest = ...;
    dispatch_group_enter(group);
    [fbRequest startWithCompletionHandler:^(...) {
        ...
        dispatch_group_leave(group);
    }
}

答案 2 :(得分:1)

不想回答我自己的问题...不喜欢这样做,并希望有一个更优雅的解决方案......但它似乎没有来,有人甚至低估了这个问题。所以我只是发布我的解决方案并关闭问题。如果你最终遇到类似的问题,并且正在读这篇文章,我通过以下方式处理:

为每个方法创建2个int。一个int立即设置为迭代的数组的计数。在每次迭代结束时,我发布了一个NSNotification。在NSNotification处理程序方法中,我正在增加第二个int&amp;每次运行if条件,检查它们是否匹配。

当有很多这样的方法发生时,跟踪所有这些是很痛苦的......所以,如果有人找到更好的解决方案,我很乐意听到它。感谢所有回答并尝试提供帮助的人,我很感激!