我如何使用此块方法?

时间:2013-10-01 14:55:01

标签: objective-c methods block

我对使用块进行客观c编程感到有些困惑。

例如,这是一个方法:

中的.h

- (void)downloadDataWithURLString:(NSString *)urlString
                completionHandler:(void(^) (NSArray * response, NSError *error))completionHandler;
<。>中的

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

我的主要问题是......如何实现此完成处理程序?数组和错误会返回哪些变量?这是代码的一个区域,但是如何告诉它在完成后该怎么做?

2 个答案:

答案 0 :(得分: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);
    }];
 }

调用者将记录一个两项数组,其中@“将我放入数组中”和@“看马,没有手”。在一个更现实的例子中,有人要求你在完成下载时给他们回电话:

- (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
}

答案 1 :(得分: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);
                  }

}];