私見、どちらも。
推奨される方法は、アクションを実行する場所を知っているオブジェクトを持つことです。
completion_block_t completionHandler = ^(id result) { ... };
AsyncOperation* op = [AsyncOperation alloc] initWithCompletion:completionHandler];
[op start]; // executes its actions on a private execution context
次に、これらの AsyncOperation オブジェクトを便利なメソッドにラップできます。
- (void) fetchUsersWithCompletion:(completion_block_t)completionHandler
{
NSDictionary* params = ...;
self.currentOperation = [[HTTPOperation alloc] initWithParams:params
completion:completionHandler];
[self.currentOperation start];
}
クライアントは、その completionHandler を実行する場所を指定することのみに関心がある場合があります。API は次のように拡張できます。
- (void) fetchUsersWithQueue:(NSOperationQueue*)handlerQueue
withCompletion:(completion_block_t)completionHandler
{
NSDictionary* params = ...;
self.currentOperation = [[HTTPOperation alloc] initWithParams:params
completion:^(id result){
// As per the documentation of HTTPOperation, the handler will be executed
// on an _unspecified_ execution context.
// Ensure to execute the client's handler on the specified operation queue:
[handlerQueue:addOperationWithBlock:^{
completionHandler(result);
}];
}];
[self.currentOperation start];
}
後者の API は次のように使用できます。
[self fetchUsersWithQueue:[NSOperation mainQueue] completion:^(id result){
self.users = result;
[self.tableView reloadData];
}];