NSSet/NSMutableSet

A set is a collection that has no sense of order, and a particular object can only appear in a set once. Sets are primarily useful for asking the question Is it in there? For example, you might have a set of URLs that are not child-appropriate. Before displaying any web page to a child, you would want to do a quick check to see if the URL is in the set. Sets do this incredibly quickly.

An employee’s assets have no inherent order, and an asset should never appear twice in the same employee’s assets collection. Change your program to use an NSMutableSet instead of an NSMutableArray for the assets relationship.

Figure 21.2  Using NSMutableSet for assets

Using NSMutableSet for assets

In Employee.h, change the variable’s declaration:

#​i​m​p​o​r​t​ ​"​P​e​r​s​o​n​.​h​"​
@​c​l​a​s​s​ ​A​s​s​e​t​;​

@​i​n​t​e​r​f​a​c​e​ ​E​m​p​l​o​y​e​e​ ​:​ ​P​e​r​s​o​n​
{​
 ​ ​ ​ ​i​n​t​ ​e​m​p​l​o​y​e​e​I​D​;​
 ​ ​ ​ ​N​S​M​u​t​a​b​l​e​S​e​t​ ​*​a​s​s​e​t​s​;​
}​
@​p​r​o​p​e​r​t​y​ ​i​n​t​ ​e​m​p​l​o​y​e​e​I​D​;​
-​ ​(​v​o​i​d​)​a​d​d​A​s​s​e​t​s​O​b​j​e​c​t​:​(​A​s​s​e​t​ ​*​)​a​;​
-​ ​(​u​n​s​i​g​n​e​d​ ​i​n​t​)​v​a​l​u​e​O​f​A​s​s​e​t​s​;​
@​e​n​d​

In Employee.m, create an instance of the correct class:

-​ ​(​v​o​i​d​)​a​d​d​A​s​s​e​t​s​O​b​j​e​c​t​:​(​A​s​s​e​t​ ​*​)​a​
{​
 ​ ​ ​ ​i​f​ ​(​!​a​s​s​e​t​s​)​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​a​s​s​e​t​s​ ​=​ ​[​[​N​S​M​u​t​a​b​l​e​S​e​t​ ​a​l​l​o​c​]​ ​i​n​i​t​]​;​
 ​ ​ ​ ​}​
 ​ ​ ​ ​[​a​s​s​e​t​s​ ​a​d​d​O​b​j​e​c​t​:​a​]​;​
 ​ ​ ​ ​[​a​ ​s​e​t​H​o​l​d​e​r​:​s​e​l​f​]​;​
}​

Build and run the program. It should function the same.

You can’t access an object in a set by index because there is no sense of order in a set. Instead, all you can do is ask Is there one of these in there? NSSet has a method:

-​ ​(​B​O​O​L​)​c​o​n​t​a​i​n​s​O​b​j​e​c​t​:​(​i​d​)​x​;​

When you send this message to a set, it goes through its collection of objects looking for an object equal to x. If it finds one, it returns YES; otherwise it returns NO.

This brings us to a rather deep question: what does equal mean? The class NSObject defines a method called isEqual:. To check if two objects are equal, you use the isEqual: method:

i​f​ ​(​[​m​y​D​o​c​t​o​r​ ​i​s​E​q​u​a​l​:​y​o​u​r​T​e​n​n​i​s​P​a​r​t​n​e​r​]​)​ ​{​
 ​ ​ ​N​S​L​o​g​(​@​"​m​y​ ​d​o​c​t​o​r​ ​i​s​ ​e​q​u​a​l​ ​t​o​ ​y​o​u​r​ ​t​e​n​n​i​s​ ​p​a​r​t​n​e​r​"​)​;​
}​

NSObject has a simple implementation of isEqual:. It looks like this:

-​ ​(​B​O​O​L​)​i​s​E​q​u​a​l​:​(​i​d​)​o​t​h​e​r​
{​
 ​ ​ ​ ​r​e​t​u​r​n​ ​(​s​e​l​f​ ​=​=​ ​o​t​h​e​r​)​;​
}​

Thus, if you haven’t overridden isEqual:, the code snippet is equivalent to:

i​f​ ​(​m​y​D​o​c​t​o​r​ ​=​=​ ​y​o​u​r​T​e​n​n​i​s​P​a​r​t​n​e​r​)​ ​{​
 ​ ​ ​N​S​L​o​g​(​@​"​m​y​ ​d​o​c​t​o​r​ ​i​s​ ​e​q​u​a​l​ ​t​o​ ​y​o​u​r​ ​t​e​n​n​i​s​ ​p​a​r​t​n​e​r​"​)​;​
}​

Some classes override isEqual:. For example, in NSString, isEqual: is overridden to compare the characters in the string. For these classes, there is a difference between equal and identical. Let’s say I have two pointers to strings:

N​S​S​t​r​i​n​g​ ​*​x​ ​=​ ​.​.​.​
N​S​S​t​r​i​n​g​ ​*​y​ ​=​ ​.​.​.​

x and y are identical if they contain the exact same address. x and y are equal if the strings they point to contain the same letters in the same order.

Thus, identical objects are always equal. Equal objects are not always identical.

Does this difference matter? Yes. For example, NSMutableArray has two methods:

-​ ​(​N​S​U​I​n​t​e​g​e​r​)​i​n​d​e​x​O​f​O​b​j​e​c​t​:​(​i​d​)​a​n​O​b​j​e​c​t​;​

-​ ​(​N​S​U​I​n​t​e​g​e​r​)​i​n​d​e​x​O​f​O​b​j​e​c​t​I​d​e​n​t​i​c​a​l​T​o​:​(​i​d​)​a​n​O​b​j​e​c​t​;​

The first steps through the collection asking each object isEqual:anObject? The second steps through the collection asking each object == anObject?

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset