You would like to store an array of objects but you don’t want any one object to appear more than once in the array.
Sets are very similar to arrays. The big difference is that sets
allow objects to be added only once. The second time you try to add
the same object, it will be rejected by the set. We use NSSet
for immutable and NSMutableSet
for mutable sets. Let’s have a
look at an example of an immutable set:
NSString *hisName = @"Robert"; NSString *hisLastName = @"Kiyosaki"; NSString *herName = @"Kim"; NSString *herLastName = @"Kiyosaki"; NSSet *setOfNames = [[NSSet alloc] initWithObjects: hisName, hisLastName, herName, herLastName, nil]; NSLog(@"Set = %@", setOfNames);
We created an immutable set and passed 4 string objects to its
initializer method. So let’s see what gets printed out to the console
window with our NSLog
:
Set = {( Kim, Robert, Kiyosaki )}
You can see that the last name
Kiyosaki
was added only once to the list.
Our set rejected the second addition of the same object to the list.
It is very important to understand that a set
doesn’t just do a comparison on where in memory an object sits, but it
actually looks into its contents. hisLastName
and herLastName
are two separate variables, and
they will sit in two different places in the memory. Our set, however,
managed to understand that we are passing instances of NSString
to it and did a comparison on the
contents of these strings to find out that we had
already added the Kiyosaki
last name to the
set. So only one instance ended up in the set.
Now let’s have a look at constructing mutable sets:
NSMutableSet *setOfNames = [[NSMutableSet alloc] initWithObjects: hisName, hisLastName, nil]; [setOfNames addObject:herName]; [setOfNames addObject:herLastName];
We simply used the addObject:
method of
NSMutableSet
to add new objects to
our set. You can also use the removeObject:
method
to remove an object. Again, remember that the contents of the object
matter, not its memory address. So if you want to remove a string from
the set, simply pass that string to the removeObject:
method, even if your new
string is in a different variable or somewhere else in memory. As long
as the contents of that string/object are the same, you will get the
results you want:
NSMutableSet *setOfNames = [[NSMutableSet alloc] initWithObjects: hisName, hisLastName, herName, herLastName, nil]; [setOfNames removeObject:@"Kiyosaki"]; NSLog(@"Set = %@", setOfNames);
And the results get printed to the console window:
Set = {( Kim, Robert )}
If you want to fast enumerate all objects in a set, use the
enumerateObjectsUsingBlock:
method. The
block object that you pass to this method should return no value and
should have two parameters:
- A key of type
id
Contains the object in the set that is being currently enumerated.
- A pointer to a boolean value of type
BOOL
If you want to stop the enumeration at any time, simply place a boolean value of type
YES
into the memory address of this variable.
Let’s have a look at an example. Let’s say I want to try to find
the string Kiyosaki
in a set that I
have:
[setOfNames enumerateObjectsUsingBlock:^(__strong id obj, BOOL *stop) { if ([obj isKindOfClass:[NSString class]]){ NSString *string = (NSString *)obj; if ([string isEqualToString:@"Kiyosaki"]){ NSLog(@"Found %@ in the set", string); *stop = YES; } } }];
If the enumeration can find a string with the value of
Kiyosaki
in the set, we print a string to
the console and terminate the enumeration by placing the value of
YES
into the second parameter of
our enumerator block object.
There are other handy methods for sets. Use the count
method to get the number of objects
currently in a set. You can also use the allObjects
method to get an array of all the
objects in the set. If you want to extract an object from the set,
with no concern for which one, call the anyObject
on your set. This method will
return, as its name implies, a random object in the set, no matter
where in the set it is. You will get nil
from this method if the set is
empty.
Get iOS 5 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.