2
typedef void (^RequestProductsCompletionHandler)(BOOL success, NSArray * products);

このコード行が .h ファイルで何をしているのか理解できません。

詳しく説明してください

  1. typedef.
  2. void (void が何をするかは知っていますが、ここでの目的は何ですか?)。
  3. (^RequestProductsCompletionHandler)(BOOL 成功、NSArray * 製品);
  4. 呼び方は?
4

3 に答える 3

9

これは、2 つのパラメーター (BOOL と NSArray) を取り、戻り値を持たない名前を持つObjective-Cブロック型の定義です。RequestProductsCompletionHandlerc 関数を呼び出すのと同じ方法で呼び出すことができます。

RequestProductsCompletionHandler handler = ^(BOOL success, NSArray * products){
    if (success){
       // Process results
    }
    else{
       // Handle error
    }
}
...
handler(YES, array);
于 2013-08-12T12:35:17.213 に答える
7

ウラジミールはそれをよく説明しました。ブール値と の配列の2 つのパラメータを渡すブロックを表す変数型を定義しますが、ブロック自体は を返します。を使用する必要はありませんが、メソッドの宣言が少し洗練されたものになります (また、ブロック変数の複雑な構文を使用する必要がなくなります)。successproductsvoidtypedef

実用的な例を挙げると、ブロック タイプの名前とそのパラメーターから、これが完了ブロック (たとえば、遅いネットワーク リクエストなどの非同期操作が完了したときに実行されるコードのブロック) を定義していると推測できます。ブロックをメソッド引数として使用するを参照してください。

たとえば、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
        });
    });
}

明らかに、これが特定の完了ハンドラ ブロックが行っていることと正確に一致する可能性は低いですが、うまくいけば概念を示しています。

于 2013-08-12T13:07:13.587 に答える