01.02.2014 Views

Objective-C Fundamentals

Objective-C Fundamentals

Objective-C Fundamentals

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

88 CHAPTER 4 Storing data in collections<br />

create a snapshot of the dictionary’s keys and then enumerate through the snapshot<br />

while modifying the original dictionary. Here’s an example of this process:<br />

NSArray *myKeys = [myDetails allKeys];<br />

for (NSString *key in myKeys) {<br />

[myDetails removeObjectForKey:key];<br />

}<br />

This works because the allKeys message creates a copy of the keys in the myDetails<br />

dictionary. The enumerator then loops through the contents of the array (and not the<br />

dictionary). Because the array is never modified, it’s safe to enumerate its contents.<br />

Each time through the loop, you modify the dictionary, indirectly causing its internal<br />

data structures to change. This doesn’t matter, however, because technically you’re<br />

not currently enumerating its contents.<br />

While discussing arrays and dictionaries, we casually mentioned that various messages<br />

won’t accept nil or that they use nil to indicate special conditions. We also<br />

mentioned that these data structures are only capable of storing objects, not primitive<br />

values such as integer or float. But most applications need to store a list of numbers,<br />

so how can you force an NSArray or NSDictionary instance to store a set of primitive<br />

values? The answer is a technique called boxing.<br />

4.3 Boxing<br />

Undoubtedly in your application you’ll come across the need to store a number such<br />

as 3, 4.86, or even a Boolean YES or NO value in an NSArray- or NSDictionary-based<br />

data structure. You may think you could accomplish this task with a code snippet such<br />

as the following:<br />

[myArray addObject:5];<br />

But when you attempt to compile this statement, the compiler will warn you that<br />

"passing argument 1 of addObject: makes pointer from integer without a cast,"<br />

hinting that something isn’t quite right. This example is a classic demonstration of the<br />

procedural C-based side of <strong>Objective</strong>-C running up against the newer object-oriented<br />

additions to the language.<br />

Classes such as NSArray and NSDictionary expect their keys and values to be<br />

objects of some kind. The integer number 5 isn’t an object: it’s a simple primitive data<br />

type. As such, it’s not possible to directly store an integer in an array.<br />

Many languages such as Java 5 and C# take care of this problem automatically<br />

through a concept called autoboxing. Behind the scenes, the primitive (non-objectoriented)<br />

value is wrapped inside a container object (a box), and this container is<br />

passed around instead of the raw value. Likewise, when you attempt to access the array<br />

and extract the value, the compiler detects a boxed value and automatically extracts<br />

the primitive payload for you. You as a developer are none the wiser to this process<br />

occurring. This process can be conceptualized in much the same way as a gift being<br />

placed inside a FedEx box and removed once it reaches its destination. FedEx can<br />

only deal with boxes of certain sizes, not your oddly shaped teapot for Aunt Betty, but

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!