typedef void (^RequestProductsCompletionHandler)(BOOL success, NSArray * products);
このコード行が .h ファイルで何をしているのか理解できません。
詳しく説明してください
- typedef.
- void (void が何をするかは知っていますが、ここでの目的は何ですか?)。
- (^RequestProductsCompletionHandler)(BOOL 成功、NSArray * 製品);
- 呼び方は?
typedef void (^RequestProductsCompletionHandler)(BOOL success, NSArray * products);
このコード行が .h ファイルで何をしているのか理解できません。
詳しく説明してください
これは、2 つのパラメーター (BOOL と NSArray) を取り、戻り値を持たない名前を持つObjective-Cブロック型の定義です。RequestProductsCompletionHandler
c 関数を呼び出すのと同じ方法で呼び出すことができます。
RequestProductsCompletionHandler handler = ^(BOOL success, NSArray * products){
if (success){
// Process results
}
else{
// Handle error
}
}
...
handler(YES, array);
ウラジミールはそれをよく説明しました。ブール値と の配列の2 つのパラメータを渡すブロックを表す変数型を定義しますが、ブロック自体は を返します。を使用する必要はありませんが、メソッドの宣言が少し洗練されたものになります (また、ブロック変数の複雑な構文を使用する必要がなくなります)。success
products
void
typedef
実用的な例を挙げると、ブロック タイプの名前とそのパラメーターから、これが完了ブロック (たとえば、遅いネットワーク リクエストなどの非同期操作が完了したときに実行されるコードのブロック) を定義していると推測できます。ブロックをメソッド引数として使用するを参照してください。
たとえば、InventoryManager
次のように定義されたインターフェイスを持つメソッドを使用して、製品情報を要求できるクラスがあるとしますtypedef
。
- (void)requestProductsWithName:(NSString *)name completion:(RequestProductsCompletionHandler)completion;
そして、次のようにメソッドを使用できます。
[inventoryManager requestProductsWithName:name completion:^(BOOL success, NSArray * products) {
// when the request completes asynchronously (likely taking a bit of time), this is
// how we want to handle the response when it eventually comes in.
for (Product *product in products) {
NSLog(@"name = %@; qty = %@", product.name, product.quantity);
}
}];
// but this method carries on here while requestProductsWithName runs asynchronously
の実装を見ると、requestProductsWithName
おそらく次のようになります。
- (void)requestProductsWithName:(NSString *)name completion:(RequestProductsCompletionHandler)completion
{
// initiate some asynchronous request, e.g.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// now do some time consuming network request to get the products here
// when all done, we'll dispatch this back to the caller
dispatch_async(dispatch_get_main_queue(), {
if (products)
completion(YES, products); // success = YES, and return the array of products
else
completion(NO, nil); // success = NO, but no products to pass back
});
});
}
明らかに、これが特定の完了ハンドラ ブロックが行っていることと正確に一致する可能性は低いですが、うまくいけば概念を示しています。