これらのガイドラインに従って、再帰ブロックを作成しました。
NSMutableArray *groups = [NSMutableArray arrayWithArray:@[@"group1", @"group2", @"group3", @"group4"];
__block CommunicationCompletionHandler completion = [^{
[groups removeObjectAtIndex:0];
if ([groups count] > 0) {
// This will send some information to the network, and calls the completion handler when it receives a response
[mySocket saveGroup:groups[0] completion:completion];
}
} copy]; // Removing copy here doesn't work either
[mySocket saveGroup:groups[0] completion:completion];
このsaveGroup:completion:
メソッドでは、完了ハンドラーを配列に追加します。
self.completionHandlers[SaveGroupCompletionHandlerKey] = [completion copy];
応答を受信したら、次のメソッドを呼び出します (key
この場合は ですSaveGroupCompletionHandlerKey
)。
- (void)performCompletionHandlerForKey:(NSString *)key {
if (self.completionHandlers[key]) {
((CommunicationCompletionHandler)self.completionHandlers[key])();
[self.completionHandlers removeObjectForKey:key];
}
}
問題は、完了ハンドラが 1 回しか呼び出されないことです。このremoveObjectForKey:
行は、ブロックの割り当てを解除します。その行のコメントを外すと、すべて正常に動作します。を追加したため、配列がこのブロックへの最後の参照をどのように持っているかわかりませんcopy
(これは に最適化されていると思いますretain
)。
わかりやすくするために、アプリの流れは次のとおりです。
- ネットワーク経由で最初のグループのデータを送信する
- 応答を受け取る
- コール完了ハンドラ
- 完了ハンドラーで、次のグループのデータを送信します (これは再帰部分です)。
私が間違っていることを指摘できる人はいますか?