方法的语法解释

时间:2015-02-08 16:40:03

标签: objective-c

我按照教程和我输入的方法如下:

+(void)downlaodDataFromURL:(NSURL *)url withCompletionHandler:(void (^)(NSData *))completionHandler{

    // Instantiate  a session configuration object
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

    // Instantiate a session object
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];

    // Create a data task object to perform the data downloading
    NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {


        if (error != nil){
            // If any error occurs then just display its description on the console
            NSLog(@" %@", [error localizedDescription]);
        }
        else {

            //If no errors occurs, check the HTTP status code.
            NSInteger HTTPStatusCode = [(NSHTTPURLResponse*)response statusCode];

            //If it's other than 200, then show it on console.
            if (HTTPStatusCode != 200){
                NSLog(@"HTTP status code = %d", HTTPStatusCode);
            }

            //Call the completion handler with the returned data on the main thread.
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                                    completionHandler  (data);
                completionHandler (data);
            }];

        }

    }];

    //Resume the task
    [task resume];

}

我有两个问题:

首先 - 在方法声明中,我见过以下:withCompletionHandler:(void (^)(NSData *))completionHandler。我从未见过像(void (^)那样的建筑。在我对方法语法的理解中,我们有参数和类型,该方法应该返回或不返回,但那是什么?我从未见过void这样的地方,(^)是什么?我知道,^意味着阻止,但那个结构怎么样?

第二 - 在

[[NSOperationQueue mainQueue] addOperationWithBlock:^{

                completionHandler (data);
            }];

我看到completionHandler (data);。有圆括号,completionHandler在top方法中声明,数据显而易见,我们从URL获取数据。但究竟是什么以及什么是 - completionHandler?当我查看(void (^)(NSData *))completionHandler时,我认为completionHandlerNSData类型的对象。这对我来说毫无意义。我猜,我只是无法正确理解语法。

请你解释一下吗?我知道这个的全部含义,但是这两段代码让我感到困惑..谢谢!

编辑:

在我的viewController.m中,我有一个声明如下的方法:

-(void)getCountryInfo{


    //Prepare the URL that we'll get the country info data from.
    NSString *URLString = [NSString stringWithFormat:@"http://api.geonames.org/countryInfoJSON?username=Necrosoft&country=%@", self.countryCode];
    NSURL *url = [NSURL URLWithString:URLString];

    [AppDelegate downlaodDataFromURL:url withCompletionHandler:^(NSData *data){

        //Check if any data returned
        if (data != nil){

            //Convert the returned data into a dictionary
            NSError *error;
            NSMutableDictionary *returnedDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

            if (error != nil){
                NSLog(@"%@", [error localizedDescription]);

        }

        else {

            self.countryDetailsDictionary = [[returnedDict objectForKey:@"geonames"] objectAtIndex:0];
            NSLog(@"%@", self.countryDetailsDictionary);

            //Set the country name to the respective label.
            self.lblCountry.text = [NSString stringWithFormat:@" %@ (%@)", [self.countryDetailsDictionary objectForKey:@"countryName"], [self.countryDetailsDictionary objectForKey:@"countryCode"]];

            //Reload the table view.
            [self.tblCountryDetails reloadData];

            //Show the table view.
            self.tblCountryDetails.hidden = NO;



             }

        }
    }];

}

上面描述了一个类方法调用:

 [AppDelegate downlaodDataFromURL:url withCompletionHandler:^(NSData *data){
...// there is code pasted above

所以,如果我理解正确,completionHandler (data);调用定义如下:

        //Check if any data returned
        if (data != nil){

            //Convert the returned data into a dictionary
            NSError *error;
            NSMutableDictionary *returnedDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

            if (error != nil){
                NSLog(@"%@", [error localizedDescription]);

        }

        else {

            self.countryDetailsDictionary = [[returnedDict objectForKey:@"geonames"] objectAtIndex:0];
            NSLog(@"%@", self.countryDetailsDictionary);

            //Set the country name to the respective label.
            self.lblCountry.text = [NSString stringWithFormat:@" %@ (%@)", [self.countryDetailsDictionary objectForKey:@"countryName"], [self.countryDetailsDictionary objectForKey:@"countryCode"]];

            //Reload the table view.
            [self.tblCountryDetails reloadData];

            //Show the table view.
            self.tblCountryDetails.hidden = NO;

当data是我们成功下载的NSData对象时:

 AppDelegate downlaodDataFromURL:url withCompletionHandler:^(NSData *data)

我是对的吗?

1 个答案:

答案 0 :(得分:1)

  

withCompletionHandler:(void (^)(NSData *))completionHandler

Objective-C方法使用C类型转换语法声明参数。所以,这可以被认为是:

withCompletionHandler:(SomeType)completionHandler

其中 SomeType void (^)(NSData *)。诚然,这是一种丑陋而混乱的语法。这意味着:阻止一个块的指针,该块接受一个NSData*参数并且不返回任何内容(返回void)。

考虑:

void foo(NSData *);

这显然是一个函数的声明,它接受NSData*参数并且不会返回任何内容。

下一步:

void (^foo)(NSData *);

这是一个名为foo的块变量的声明,它接受NSData*参数并且不会返回任何内容。

现在,要将其设为一个类型,请删除名称foo

void (^)(NSData *)

这是我上一个示例中foo的类型和代码中的completionHandler参数。

希望这有助于回答您的第二个问题。代码:

completionHandler (data);

completionHandler块的调用。它将data作为参数传递给块,该块与块的已知类型匹配。