2

这是 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关键词?

4

3 回答 3

2

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

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

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


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

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 中的学习块有一些学习曲线.. 但是一旦你掌握了它.. 它是一个了不起的工具。请在此处查看我的答案,以查看块的一些示例用途。

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

于 2013-07-17T05:05:53.870 回答
1

当 API 调用成功时,该块作为要调用的内容传递到方法中。globalTimelinePostsWithBlock将调用与数据一起传入的块(可能还有一个NSError

block在这种情况下不是关键字,它只是变量的名称。

如果你想使用globalTimelinePostsWithBlock,你可以这样称呼它

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

ClassName类的名称在哪里globalTimelinePostsWithBlock定义)

于 2013-07-17T05:04:27.750 回答
1

块定义类似于 C 函数。

(void (^)(NSArray *posts, NSError *error))block
  • 初始void定义函数的返回类型。
  • ^块指针。类似于*对象。
  • (NSArray *posts, NSError *error)是带有变量名的参数。
  • block是存储此块的变量。(此处取名不好)
于 2013-07-17T05:07:55.970 回答