1

我有多种方法,每种方法都有嵌套循环和 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 ?

4

3 回答 3

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。

于 2013-03-09T06:31:08.143 回答
1

这种行为是意料之中的,因为您正在呼叫dispatch_group_enter然后立即呼叫dispatch_group_leave,这意味着该组无需等待。

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

在此处检查接受的答案: 等到多个网络请求全部执行 - 包括它们的完成块

更新: 对于给定的示例,您可以dispatch_group_enter在每次调用之前调用startWithCompletionHandler:,并dispatch_group_leave在完成块的末尾调用:

for (...) {
    FBRequest *fbRequest = ...;
    dispatch_group_enter(group);
    [fbRequest startWithCompletionHandler:^(...) {
        ...
        dispatch_group_leave(group);
    }
}
于 2013-03-09T09:02:22.407 回答
1

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

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

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

于 2013-04-02T19:54:41.810 回答