iPhone : Unable to understand the following coding
I have do开发者_C百科wnloaded some example coding. But I found strange coding or maybe I have seen it first time.
Can anybody help me to understand following coding?
NSArray *wordStrings = [response.spellingSuggestions wn_map: ^id (id obj) {
return [obj word];
}];
Let's break it apart, from the inside out.
[obj word]
A message with the selector word
to the object whose pointer is in the variable obj
.
return [obj word];
A statement returning the value returned by that message.
^id (id obj) {
return [obj word];
}
Here things get interesting.
This is a block. Let's disassemble it:
^
: It's a block!id
: Return type. This block returns an object pointer (id
).(id obj)
: Arguments. It takes one, which is theobj
variable used as the receiver in the message expression. As we can guess from its name and as is made explicit here, it is also an object pointer.{ … }
: The body of the block.
So, a block taking one object and returning an object.
[response.spellingSuggestions wn_map: ^id (id obj) {
return [obj word];
}]
The block is passed to a wn_map:
message. Let's drill back inward, at the other end of this message expression:
response.spellingSuggestions
This is actually another message expression. It sends the spellingSuggestions
message to the object whose pointer is in the response
variable. This sort of expression is called a property access expression, because spellingSuggestions
should be a formal property (declared with @property
), but ultimately it's just another Objective-C message.
Or response
could be a structure and this expression a structure member access, but in modern Objective-C code, that's unlikely. Only you know, since you didn't show the declaration of response
. If its type is id
or SomeObjectiveCClass *
, this is a message expression. If its type is something else, with or without the struct
keyword but definitely without an *
, then it is a structure member access expression.
Either way, this expression evaluates to an object pointer, presumably an object that somehow encapsulates or lists spelling suggestions.
[response.spellingSuggestions wn_map: ^id (id obj) {
return [obj word];
}]
… which you then send the wn_map:
message to, passing the block. I'd guess that the wn_map:
method will call the block for every spelling suggestion…
NSArray *wordStrings = [response.spellingSuggestions wn_map: ^id (id obj) {
return [obj word];
}];
… and return a pointer to an NSArray, which you initialize the wordStrings
variable with.
Incidentally, another way to write this (assuming wn_map:
does what I think it does) would have been:
NSArray *wordStrings = [response valueForKeyPath:@"spellingSuggestions.word"];
or:
NSArray *wordStrings = [response.spellingSuggestions valueForKey:@"word"];
The former will do the latter as part of its work (and the former will also use valueForKey:
to get response.spellingSuggestions
, rather than just sending [response spellingSuggestions]
as the original code and the latter revision do).
Assuming spellingSuggestions
returns an NSArray, this valueForKey:
message to that array will do the same thing as wn_map:
and the block: Send the word
message to each suggestion, and gather the results into a new array—the one you assign to wordStrings
.
This is the blocks construct for Objective-C. What this code means, in human terms, is the following:
- Take an array filled with objects
- Build a new array starting from it, where each item of the new array is creating "mapping" the old item through the proposed anonymous method (i.e. all that is after the
^
character)
So, if the response.spellingSuggestions
object is an instance of NSArray
filled with objects which respond to the method word
, you will obtain a new array where each object is the result of the [obj word]
call. E.g. you can use this approach to convert a list of objects in a list of the corresponding string description.
Update
You can find more information about the block construct at the Apple Developer reference page, as stated by @Steven in his answer.
Hope this helps
This is the "blocks" construct. See, e.g., http://developer.apple.com/library/ios/#documentation/general/conceptual/DevPedia-CocoaCore/Block.html
精彩评论