0

我对使用块的目标 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!?
}

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

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);
    }];
 }

调用者将使用@“把我放入一个数组”和@“看,妈妈,没有手”来记录一个包含两项的数组。在一个更现实的例子中,假设有人要求您在完成下载后给他们回电:

- (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 回答