You want to store key-value data in an object, or you would like to retrieve objects from an array using a key into the array, but arrays won’t quite suffice for this purpose, as they do not facilitate finding objects inside the array using a key or a marker for that object.
A dictionary is a special container for objects in which each object is given a key, which itself is an object. That is one of the key differences between dictionaries and arrays. An array has a numeric index into each item/object that it holds, whereas a dictionary holds a key to each item. I’ll show you what I mean.
Let’s say we want to store a person’s first name, last name, and age into an array and then into a dictionary. This is how we would store those values in an array:
NSArray
*
person
=
@
[
@"Anthony"
,
@"Robbins"
,
@
51
];
NSLog
(
@"First Name = %@"
,
person
[
0
]);
NSLog
(
@"Last Name = %@"
,
person
[
1
]);
NSLog
(
@"Age = %@"
,
person
[
2
]);
You can see that we are using an index into the array to access
each one of these values. With dictionaries, we give each value a
key, which is an object, and then use that key to
access those values. Let’s look at the same example but this time using
dictionaries. We have a "First Name"
key with the value "Anthony"
and so
on:
NSDictionary
*
person
=
@
{
@"First Name"
:
@"Anthony"
,
@"Last Name"
:
@"Robbins"
,
@"Age"
:
@
51
};
NSLog
(
@"First Name = %@"
,
person
[
@"First Name"
]);
NSLog
(
@"Last Name = %@"
,
person
[
@"Last Name"
]);
NSLog
(
@"Age = %@"
,
person
[
@"Age"
]);
The results will then be printed out as shown here:
First Name = Anthony Last Name = Robbins Age = 51
As you can see, we initialized the dictionary with values and
keys. We give a value followed by the key for that value. When we used
NSLog
, we printed out each value by
handing the key to the dictionary’s objectForKey:
method.
The mutable version of NSDictionary
, NSMutableDictionary
, can be modified after it
has been allocated and initialized. For instance, if we want to remove
the object associated with the key Age
from
our dictionary after its initialization, we would use a mutable
dictionary like so:
NSMutableDictionary
*
person
=
[
@
{
@"First Name"
:
@"Anthony"
,
@"Last Name"
:
@"Robbins"
,
@"Age"
:
@
51
}
mutableCopy
];
[
person
removeObjectForKey:
@"Age"
];
NSLog
(
@"First Name = %@"
,
person
[
@"First Name"
]);
NSLog
(
@"Last Name = %@"
,
person
[
@"Last Name"
]);
NSLog
(
@"Age = %@"
,
person
[
@"Age"
]);
We have simply removed the object associated with the key
Age
. The results printed to the console
window will be similar to this:
First Name = Anthony Last Name = Robbins Age = (null)
Note
"Age"
is not just empty, but
totally missing.
If you want to enumerate all keys with their objects inside a
dictionary, you can simply use the enumerateKeysAndObjectsUsingBlock:
method of
the dictionary. In the previous example, the method would print the
"First Name"
and "Last Name"
elements, but not "Age"
, because we removed it. The parameter to
this method is a block object with no return value and three
parameters:
- Key
An
id
that tells you which key is being enumerated at the moment.- Object
An
id
that gives you the object associated with the key being currently enumerated.- A pointer to a value of type
BOOL
At any point during the enumeration, if you want to stop the process, you can simply put the value
YES
into this pointer’s memory address. Keep it untouched if you want to enumerate through all the keys in the dictionary.
Let’s see an example:
NSDictionary
*
person
=
@
{
@"First Name"
:
@"Anthony"
,
@"Last Name"
:
@"Robbins"
,
@"Age"
:
@
51
};
[
person
enumerateKeysAndObjectsUsingBlock:
^
(
__strong
id
key
,
__strong
id
obj
,
BOOL
*
stop
)
{
NSLog
(
@"Key = %@, Object For Key = %@"
,
key
,
obj
);
}];
And the results, which get printed to the console window, are shown here:
Key = Last Name, Object For Key = Robbins Key = First Name, Object For Key = Anthony Key = Age, Object For Key = 51
If you want to do a manual fast enumeration without block objects,
you can use the allKeys
method of the
dictionary to go through all methods and, once you enumerate the keys,
use the keys to find the objects associated with the keys using the
objectForKey:
method, like so:
for
(
id
keyInDictionary
in
[
person
allKeys
]){
id
objectForKey
=
[
person
objectForKey:
keyInDictionary
];
NSLog
(
@"Key = %@, Object For Key = %@"
,
keyInDictionary
,
objectForKey
);
}
Bear in mind that you can traverse the keys in a dictionary in various
ways. We’ve just seen two ways of doing this. There is another method
that we can use: calling the keyEnumerator
method of the dictionary to get
an object of type NSEnumerator
. Here
is an example:
NSEnumerator
*
keys
=
[
person
keyEnumerator
];
id
keyInDictionary
=
nil
;
while
((
keyInDictionary
=
[
keys
nextObject
])
!=
nil
){
id
objectForKey
=
[
person
objectForKey:
keyInDictionary
];
NSLog
(
@"Key = %@, Object For Key = %@"
,
keyInDictionary
,
objectForKey
);
}
Get iOS 6 Programming Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.