需要解释块的这种用法作为方法参数

时间:2013-07-17 05:01:22

标签: objective-c

这是AFNetworking示例代码的片段:

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

我不明白的是:

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

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

3 个答案:

答案 0 :(得分:2)

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

我建议你花点时间了解它自己的obj-c中的块语法..然后看一下使用它们的例子。这个tutorial很棒(两部分)..

我做了你以前做过的事情......然后把头发拉了一半......看完上面的教程后......我的头发长了起来:)


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

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

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

// 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。在第一个问题之后,有人可以为我解释语法吗?为什么最后会有一个block关键字?

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

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

再次理解如何/为什么..我建议你看看上面的文章..在obj-c中学习块有一点学习曲线..但是一旦你掌握了它...它是一个了不起的工具。请在这里查看我的answer以查看块的一些示例用法。

Here也是一个示例问题/答案,提供了将委托转换为基于块的方法的案例研究,该方法还可以说明块如何工作。

答案 1 :(得分:1)

当API调用成功时,将块作为要调用的内容传递给方法。 globalTimelinePostsWithBlock将调用传入的数据块(可能还有NSError

在这种情况下,

block不是关键字,它只是变量的名称。

如果您想使用globalTimelinePostsWithBlock,则可以将其称为

[ClassName globalTimelinePostsWithBlock:^(NSArray *posts, NSError *error) {
  // Check error, then do something with posts
}];

(其中ClassName是定义的类globalTimelinePostsWithBlock的名称)

答案 2 :(得分:1)

块定义类似于C函数。

(void (^)(NSArray *posts, NSError *error))block
  • 初始void定义函数的返回类型。
  • ^是块指针。与对象的*类似。
  • (NSArray *posts, NSError *error)是具有变量名称的参数。
  • block是存储此块的变量。 (这里命名不好)