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中調用這些方法。有沒有辦法設置某種完成處理程序來將這些方法的調用放在裏面?然後在全部完成後發佈NSN通知?

+1

未經評論或解釋而投票棄權的問題???這是有幫助的... – 2013-03-13 01:08:51

回答

1

不想回答我自己的問題......不喜歡這樣做,並希望有一個更優雅的解決方案......但它似乎並沒有到來,索姆甚至會降低這個問題。所以我只是要發佈我的解決方案並解決問題。如果你最終遇到類似的問題並正在閱讀本文,我通過以下方式處理它:

爲每種方法創建2個int。一個int會立即設置爲正在迭代的數組的數量。在每次迭代結束時,我發佈了NSNotification。在NSNotification處理程序方法中,我每次運行if條件時都會遞增第二個int &,檢查它們是否匹配。

當這種情況有很多種方法發生時,記住所有這些信息是很痛苦的......所以如果有人找到更好的解決方案,我很樂意聽到它。感謝所有回答並試圖提供幫助的人,我感激不盡!

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。

+0

感謝您的答覆,我檢查了反應。問題並不在於facebook,並且知道何時完成服務器調用......我想知道更多關於何時完成所有嵌套循環的迭代。但我會研究這是否有一些方法來設置嵌套循環完成的通知系統。 – 2013-03-09 14:03:14

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); 
    } 
} 
+0

雖然這是問題,但我不知道在哪裏調用dispatch_group_leave。上面的代碼只是爲了展示我一直在嘗試的想法......不是我嘗試過的唯一的事情。我已經把dispatch_group_leave放在了我能想到的地方,但沒有成功。如果我只是把它作爲每個方法的最後一行,在服務器調用完成之前不起作用併發生通知。我不能將它放在服務器調用的完成塊中,因爲服務器調用發生在通過不同id的循環中,所以group_leave會在第一次迭代時出現衝突。 – 2013-03-09 14:01:31

+0

在上面的代碼中,我可以放置dispatch_group_leave以便在整個方法完成後離開?意思是在每個嵌套循環的每次迭代之後?是否可以將調用方法(從viewdidappear)放入塊中?像'blah_blah_completion(block^{[self runLoopMethod1];});'' ??? – 2013-03-09 14:08:08

+0

我添加了更多詳細信息,請再次檢查答案。 – Hejazi 2013-03-10 17:40:29

相關問題