1

I'm creating objects and adding them to a set using -[NSOrderedMutableSet addObject:], but I discovered that only duplicates of the objects themselves are checked for -- the object pointer's address presumably, and that it's possible to add multiple objects that have identical content.

For example:

SomeObject* object = [SomeObject alloc] initWithStuff:stuff];
SomeObject* object2 = [SomeObject alloc] initWithStuff:stuff];

[set addObject:object];
[set addObject:object];
[set addObject:object1];
[set addObject:object2];

The count will be 2.

This makes me wonder what the point of these classes is? Under what circumstances might one have an object and not know if the object itself had already been added to a collection, rather than the data contained within the object?

Whats the easiest way (or what class should I use) to use to ensure the set only contains one of each object based on content?

jscs
  • 63,694
  • 13
  • 151
  • 195
Gruntcakes
  • 37,738
  • 44
  • 184
  • 378
  • possible duplicate of [NSSet containsObject Not Working?](http://stackoverflow.com/questions/11144616/nsset-containsobject-not-working) – jscs Jun 26 '12 at 19:48

2 Answers2

4

The way you are looking is the right way, you are forgetting a small detail: how could the NSMutableOrderedSet class know about which instances of SomeObject contain same values?

The answer is simple: you must provide your own implementations of

- (BOOL)isEqual:(id)anObject
- (NSUInteger)hash

So that your instances will return true when compared with same internal values, and two instances with same data will have same hashcode.

Apart from this sets are rather useful because they give you better complexity on checking if an instance is contained in a set or not, and you can quickly do many logical operations on them, like intersection, union, difference and whatever.

Jack
  • 131,802
  • 30
  • 241
  • 343
  • Thanks - they should add that part to the documentation for NSMutableOrderedSet, it doesn't get a mention anywhere except for removeObjectsInArray! Very unhelpful documentation. – Gruntcakes Jun 26 '12 at 19:54
  • @Chris: Apple doesn't repeat information in subclasses; you can find mention of `isEqual:` and `hash:` in [the `NSSet` docs](http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSSet_Class/Reference/Reference.html) or the [Collections Programming Guide](http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Collections/Articles/Sets.html#//apple_ref/doc/uid/20000136-SW1). – jscs Jun 26 '12 at 19:57
  • The documentation for NSSet says to refer to the documentation for NSObject for hash, but hash isn't mentioned at all in the NSObject documentation. Oh well, guess I can find some examples on google. CHeers – Gruntcakes Jun 26 '12 at 20:03
  • @Chris: [`hash`](http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/doc/uid/20000052-BBCGFFCH) and [`isEqual:`](http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/doc/uid/20000052-BBCCECDG) are (as the `NSSet` docs state) in the `NSObject` _protocol_. Most of the method names in the docs are clickable links. – jscs Jun 26 '12 at 20:05
1

If it is a custom object you have, you'd have to implement your own isEqual: and hash method to check for equality and prevent duplicates in the set.

Mario
  • 4,530
  • 1
  • 21
  • 32