iPhone:无法理解以下编码

Dev*_*ang 16 cocoa cocoa-touch objective-c objective-c-blocks

我已经下载了一些示例编码.但我发现奇怪的编码或者我第一次看到它.

任何人都可以帮我理解下面的编码吗?

NSArray *wordStrings = [response.spellingSuggestions wn_map: ^id (id obj) {
    return [obj word];
}];
Run Code Online (Sandbox Code Playgroud)

Pet*_*sey 46

让我们从内到外将它分开.

[obj word]
Run Code Online (Sandbox Code Playgroud)

带有word指针位于变量中的对象的选择器的消息obj.

return [obj word];
Run Code Online (Sandbox Code Playgroud)

返回该消息返回的值的语句.

^id (id obj) {
    return [obj word];
}
Run Code Online (Sandbox Code Playgroud)

事情变得有趣.

这是一个块.让我们拆解它:

  • ^:这是一个块!
  • id:返回类型.该块返回一个对象指针(id).
  • (id obj):参数.它需要一个,它是obj在消息表达式中用作接收器的变量.正如我们可以从它的名字中猜出的那样,这里也是明确的,它也是一个对象指针.
  • { … }:块体.

所以,一个块占用一个对象并返回一个对象.

[response.spellingSuggestions wn_map: ^id (id obj) {
    return [obj word];
}]
Run Code Online (Sandbox Code Playgroud)

该块传递给wn_map:消息.让我们向内钻取,在此消息表达式的另一端:

response.spellingSuggestions
Run Code Online (Sandbox Code Playgroud)

这实际上是另一个消息表达式.它将spellingSuggestions消息发送到其指针位于response变量中的对象.这种表达式称为属性访问表达式,因为它spellingSuggestions应该是一个正式的属性(声明着@property),但最终它只是另一个Objective-C消息.

或者response可以是一个结构,这个表达式是一个结构成员访问,但在现代的Objective-C代码中,这是不太可能的.只有你知道,因为你没有显示声明response.如果它的类型是id或SomeObjectiveCClass *,则这是一个消息表达式.如果它的类型是别的,有或没有struct关键字但绝对没有*,那么它是一个结构成员访问表达式.

无论哪种方式,此表达式都会计算为一个对象指针,可能是一个以某种方式封装或列出拼写建议的对象.

[response.spellingSuggestions wn_map: ^id (id obj) {
    return [obj word];
}]
Run Code Online (Sandbox Code Playgroud)

...然后你发送wn_map:消息,传递块.我猜这个wn_map:方法会为每个拼写建议调用块...

NSArray *wordStrings = [response.spellingSuggestions wn_map: ^id (id obj) {
    return [obj word];
}];
Run Code Online (Sandbox Code Playgroud)

...并返回指向NSArray的指针,您可以使用该指针初始化wordStrings变量.


顺便说一句,写这个的另一种方式(假设wn_map:我认为它做了)将是:

NSArray *wordStrings = [response valueForKeyPath:@"spellingSuggestions.word"];
Run Code Online (Sandbox Code Playgroud)

要么:

NSArray *wordStrings = [response.spellingSuggestions valueForKey:@"word"];
Run Code Online (Sandbox Code Playgroud)

前者将后者作为其工作的一部分(前者也将valueForKey:用于获取response.spellingSuggestions,而不是仅仅发送[response spellingSuggestions]原始代码和后者修订版).

假设spellingSuggestions返回一个NSArray,该valueForKey:消息到该数组将执行wn_map:与块相同的操作:将word消息发送到每个建议,并将结果收集到一个新数组 - 您指定的数组wordStrings.

  • 对一个相当薄的问题进行了彻底彻底的回答 (5认同)

mar*_*wer 7

这是Objective-C的块构造.从人的角度来看,这段代码的含义如下:

  1. 拿一个装满物体的阵列
  2. 从它开始构建一个新数组,其中新数组的每个项目都通过建议的匿名方法创建"映射"旧项目(即所有在该^字符之后)

因此,如果response.spellingSuggestions对象是NSArray填充了响应方法的对象的实例word,则将获得一个新数组,其中每个对象都是[obj word]调用的结果.例如,您可以使用此方法转换相应字符串描述列表中的对象列表.

更新

您可以在Apple Developer参考页面上找到有关块结构的更多信息,如@Steven在其答案中所述.

希望这可以帮助

  • 为什么你把"COCOA"全部加盖?它不是首字母缩略词. (2认同)