Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone : Unable to understand the following coding

I have downloaded 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];
}];
like image 681
Devang Avatar asked May 10 '11 09:05

Devang


People also ask

Why do I get an error message when I try to update my iPhone?

You might be unable to update your iPhone or iPad wirelessly — or over the air — for one of these reasons: Your device doesn't support the latest software. There isn't enough available storage space on your device. The update takes a long time to download.


3 Answers

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 the obj 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.

like image 72
Peter Hosey Avatar answered Oct 13 '22 01:10

Peter Hosey


This is the blocks construct for Objective-C. What this code means, in human terms, is the following:

  1. Take an array filled with objects
  2. 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

like image 44
marzapower Avatar answered Oct 13 '22 01:10

marzapower


This is the "blocks" construct. See, e.g., http://developer.apple.com/library/ios/#documentation/general/conceptual/DevPedia-CocoaCore/Block.html

like image 30
Steven Kramer Avatar answered Oct 13 '22 01:10

Steven Kramer