0

ブロックを使用した目的の C プログラミングについて少し混乱しています。

たとえば、次の方法があります。

.h で

- (void)downloadDataWithURLString:(NSString *)urlString
                completionHandler:(void(^) (NSArray * response, NSError *error))completionHandler;

.m で:

- (void)downloadedDataURLString:(NSString *)urlString
                completionHandler:(void (^)(NSArray *, NSError *))completionHandler {
// some things get done here. But what!?
}

私の主な質問は....この完了ハンドラをどのように実装するのですか? 配列とエラーで返される変数は何ですか? これはコードの 1 つの領域ですが、コードが完成したときに何をすべきかをどのように伝えるのでしょうか?

4

2 に答える 2

1

メソッド (ブロックの本体) によって実行されるコードを提供するのは、呼び出し元次第です。そのコードを呼び出すのは、実装者次第です。

簡単な例から始めると、呼び出し元が単に urlString で配列を形成してコールバックすることを望んでいたとします。その場合、次のようにします。

- (void)downloadedDataURLString:(NSString *)urlString
                completionHandler:(void (^)(NSArray *, NSError *))completionHandler {

    NSArray *callBackWithThis = @[urlString, @"Look ma, no hands"];
    completionHandler(callBackWithThis, nil);
}

呼び出し元は次のようにします。

- (void)someMethodInTheSameClass {

    // make an array
    [self downloadedDataURLString:@"put me in an array"
                   completionHandler:^(NSArray *array, NSError *error) {
        NSLog(@"called back with %@", array);
    }];
 }

呼び出し元は、@"put me in a array" と @"Look ma, no hands" を使用して 2 つの項目の配列をログに記録します。より現実的な例として、何かをダウンロードし終わったら、電話をかけ直すよう誰かに頼まれたとします。

- (void)downloadedDataURLString:(NSString *)urlString
                completionHandler:(void (^)(NSArray *, NSError *))completionHandler {
    // imagine your caller wants you to do a GET from a web api
    // stripped down, that would look like this

    // build a request
    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    // run it asynch
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

        if (!error) {
            // imagine that the api answers a JSON array.  parse it
            NSError *parseError;
            id parse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&parseError];

            // here's the part you care about:  the completionHandler can be called like a function.  the code the caller supplies will be run
            if (!parseError) {
                completionHandler(parse, nil);
            } else {
                NSLog(@"json parse error, error is %@", parseError);
                completionHandler(nil, parseError);
            }
        } else {
            NSLog(@"error making request %@", error);
            completionHandler(nil, error);
        }
    }];

    // remember, this launches the request and returns right away
    // you are calling the block later, after the request has finished
}
于 2013-10-01T15:04:32.530 に答える
0

メソッドの詳細やその正確な実装を見ないと完全にはわかりませんが、このメソッドは新しいバックグラウンド スレッドを作成し、サーバーからデータを取得し、JSON/XML をNSArray response. エラーが発生した場合、errorオブジェクトには へのポインターが含まれますNSError。それを行った後、完了ハンドラーがメインスレッドで呼び出されます。完了ハンドラーは、データの取得を試みた後に実行するコードを指定できるブロックです。
開始するためにこのメソッドを呼び出す方法のサンプル コードを次に示します。

[self downloadDataWithURLString:@"http://www.google.com"
              completionHandler:^(NSArray *response, NSError *error) {
                  if (! error) {
                      // Do something awesome with the 'response' array
                  } else {
                      NSLog(@"An error occured while downloading data: %@", error);
                  }

}];
于 2013-10-01T15:02:46.013 に答える