需要解释块作为方法参数的这种用法 [英] Need explanation for this usage of block as method parameter

查看:42
本文介绍了需要解释块作为方法参数的这种用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是 AFNetworking 示例代码的片段:

+ (void)globalTimelinePostsWithBlock:(void (^)(NSArray *posts, NSError *error))block {[[AFAppDotNetAPIClient sharedClient] getPath:@"stream/0/posts/stream/global" 参数:nil 成功:^(AFHTTPRequestOperation *operation, id JSON) {NSArray *postsFromResponse = [JSON valueForKeyPath:@"data"];NSMutableArray *mutablePosts = [NSMutableArray arrayWithCapacity:[postsFromResponse count]];for (NSDictionary *postFromResponse 中的属性) {Post *post = [[Post alloc] initWithAttributes:attributes];[mutablePosts addObject:post];}如果(块){block([NSArray arrayWithArray:mutablePosts], nil);}} 失败:^(AFHTTPRequestOperation *operation, NSError *error) {如果(块){块([NSArray 数组],错误);}}];}

我不明白的是:

  1. (void (^)(NSArray *posts, NSError *error))block 部分.假设它是一个块,是否意味着该块是globalTimelinePostsWithBlock方法的参数?

  2. 在第一个问题之后,谁能为我解释一下语法?为什么最后有一个block关键字?

解决方案

如果你不知道块是如何工作的..那么不要费心试图通过查看代码来理解它(即使你已经使用了 lambda/anonymous 函数在其他语言(如 javascript 或 ruby​​)中.b/c,objective-c 语法是它自己的一个类.

我建议您花时间自己了解 obj-c 中的块语法..然后查看使用它们的示例.这个教程非常好(两部分).>

我做了你之前做的事情..拔掉了我一半的头发..看了上述教程后..我的头发又长回来了:)

<小时>

只是为了好玩,我会尝试解决您的具体问题:

1. (void (^)(NSArray *posts, NSError *error))块部分.假设它是一个块,是否意味着该块是 globalTimelinePostsWithBlock 方法的参数?

是的..所以这是调用此方法的一种方式:

//先定义块变量void(^block)(NSArray *posts, NSError *error) = (NSArray *posts,NSError *error) {//块体//帖子和错误会被调用块的方法传递给这个块.//所以如果你看下面的代码示例..//帖子将是 [NSArray arrayWithArray:mutablePosts]//并且错误将为零}//调用函数[AFNetworking globalTimelinePostsWithBlock:block];

2.在第一个问题之后,任何人都可以为我解释语法吗?为什么最后会有block关键字?

基本上块关键字是参数的名称..注意它在方法体中的使用方式:

if (block) {块([NSArray arrayWithArray:mutablePosts], nil);}

再次了解如何/为什么..我建议您查看上面的文章.. obj-c 中的学习块有一些学习曲线.. 但是一旦您掌握了它.. 它是一个了不起的工具.请在此处查看我的答案以了解块的一些示例用途.

这里也是一个示例问题/提供将委托转换为基于块的方法的案例研究的答案,这也可以说明块的工作原理.

This is a snippet from AFNetworking's sample code:

+ (void)globalTimelinePostsWithBlock:(void (^)(NSArray *posts, NSError *error))block {
    [[AFAppDotNetAPIClient sharedClient] getPath:@"stream/0/posts/stream/global" parameters:nil success:^(AFHTTPRequestOperation *operation, id JSON) {
        NSArray *postsFromResponse = [JSON valueForKeyPath:@"data"];
        NSMutableArray *mutablePosts = [NSMutableArray arrayWithCapacity:[postsFromResponse count]];
        for (NSDictionary *attributes in postsFromResponse) {
            Post *post = [[Post alloc] initWithAttributes:attributes];
            [mutablePosts addObject:post];
        }

        if (block) {
            block([NSArray arrayWithArray:mutablePosts], nil);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        if (block) {
            block([NSArray array], error);
        }
    }];
}

What I don't understand are:

  1. The (void (^)(NSArray *posts, NSError *error))block part. Assuming that it is a block, does it mean the block is a parameter of the globalTimelinePostsWithBlock method?

  2. Following the first question, can anyone explain the syntax for me? Why is there a block keyword in the end?

解决方案

if you don't know how blocks work.. then don't bother trying to understand it just by looking at the code (even if you have used lambda/anonymous functions in other languages like javascript or ruby).. b/c the objective-c syntax is a class on it's own..

i'd recommend you take the time to understand block syntax in obj-c on it's own.. then take a look at examples that use them. This tutorial is excellent (two parts)..

I did what you did before.. and pulled out half my hair.. after looking at the said tutorial.. my hair grew right back up :)


just for fun i'll try to address your specific questions:

1.The (void (^)(NSArray *posts, NSError *error))block part. Assuming that it is a block, does it mean the block is a parameter of the globalTimelinePostsWithBlock method?

yes it is.. so this is a way of calling this method:

// first define the block variable
void(^block)(NSArray *posts, NSError *error) = (NSArray *posts,NSError *error) {

   // block body
   // posts and error would have been passed to this block by the method calling the block.
   // so if you look at the code sample below.. 
   // posts would be [NSArray arrayWithArray:mutablePosts]
   // and error would just be nil
}

// call the function
[AFNetworking globalTimelinePostsWithBlock:block];    

2. Following the first question, can anyone explain the syntax for me? Why is there a block keyword in the end?

basically the block keyword is the name of the argument.. notice how it's used in the body of the method:

if (block) {
            block([NSArray arrayWithArray:mutablePosts], nil);
        }

again to understand how/why.. i recommend you look at the above article.. learning blocks in obj-c has a bit of learning curve.. but once you master it.. it's an amazing tool. please take a look at my answer here to see some sample uses for blocks.

Here is also a sample question/answer that provides a case study of converting delegation into a block based approach, which can also illustrate how blocks work.

这篇关于需要解释块作为方法参数的这种用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆