让我们从内到外分解它。
[obj word]
带有选择器word 的消息发送给指针位于变量obj 中的对象。
return [obj word];
返回该消息返回值的语句。
^id (id obj) {
return [obj word];
}
这里的事情变得有趣了。
这是一个方块。让我们拆解它:
-
^: 是块!
-
id:返回类型。此块返回一个对象指针 (id)。
-
(id obj):争论。它需要一个,即在消息表达式中用作接收者的obj 变量。正如我们可以从它的名字中猜到的那样,正如这里明确指出的那样,它也是一个对象指针。
-
{ … }:块的主体。
所以,一个块接受一个对象并返回一个对象。
[response.spellingSuggestions wn_map: ^id (id obj) {
return [obj word];
}]
块被传递给wn_map: 消息。让我们向内追溯,在此消息表达式的另一端:
response.spellingSuggestions
这实际上是另一个消息表达式。它将spellingSuggestions 消息发送到指针位于response 变量中的对象。这种表达式称为属性访问表达式,因为spellingSuggestions 应该是一个正式的属性(用@property 声明),但最终它只是另一个Objective-C 消息。
或者response 可能是一个结构,而这个表达式是一个结构成员访问,但在现代Objective-C 代码中,这不太可能。只有你知道,因为你没有显示response 的声明。如果它的类型是id 或SomeObjectiveCClass *,这是一个消息表达式。如果它的类型是别的东西,有或没有struct关键字,但绝对没有*,那么它就是一个结构成员访问表达式。
无论哪种方式,这个表达式的计算结果都是一个对象指针,大概是一个以某种方式封装或列出拼写建议的对象。
[response.spellingSuggestions wn_map: ^id (id obj) {
return [obj word];
}]
... 然后您将wn_map: 消息发送到,传递块。我猜wn_map: 方法会为每个拼写建议调用该块……
NSArray *wordStrings = [response.spellingSuggestions wn_map: ^id (id obj) {
return [obj word];
}];
... 并返回一个指向 NSArray 的指针,您可以用它来初始化 wordStrings 变量。
顺便说一句,另一种写法(假设 wn_map: 做了我认为的)是:
NSArray *wordStrings = [response valueForKeyPath:@"spellingSuggestions.word"];
或:
NSArray *wordStrings = [response.spellingSuggestions valueForKey:@"word"];
前者会将后者作为其工作的一部分(并且前者还将使用valueForKey: 来获取response.spellingSuggestions,而不是像原始代码那样仅发送[response spellingSuggestions],而后者的修订版则这样做)。
假设 spellingSuggestions 返回一个 NSArray,这个 valueForKey: 消息到该数组将做同样的事情 wn_map: 和块:发送 word 消息到每个建议,并将结果收集到一个新数组中——你分配给wordStrings的那个。