这是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);
}
}];
}
我不明白的是:
(void (^)(NSArray *posts, NSError *error))block
部分。假设它是一个块,是否意味着该块是globalTimelinePostsWithBlock
方法的参数?
在第一个问题之后,有人可以为我解释语法吗?为什么最后会有block
个关键字?
答案 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
是存储此块的变量。 (这里命名不好)