Ran into a interesting little problem. I was writing a method to filter an array to the unique objects:
- (NSArray*)distinctObjectsByAddress {
NSSet* uniqueSet = [NSSet setWithArray:self];
NSArray* retArray = [uniqueSet allObjects];
return retArray;
}
and wrote a unit test to check:
- (void)testDistinctObjectsByAddress5 {
Person* adam1 = [[Person alloc] initWithFirstName:@"adam" lastName:@"adam" andParent:nil];
Person* adam2 = [[Person alloc] initWithFirstName:@"adam" lastName:@"adam" andParent:nil];
testPersonArray = [NSArray arrayWithObjects:adam1,adam2, nil];
NSArray* checkArray = [testPersonArray distinctObjectsByAddress];
STAssertEquals([checkArray count], [testPersonArray count], @"Array %@ counts should match %@ %@",checkArray,adam1,adam2);
}
Pretty simple. The interesting part is that about 80-90% of the time the test passes and every so often it fails because the distinctObjectsByAddress
method only returns one object. I've been able to trace it to the [NSSet setWithArray:self]
call but I've also been able to verify that the two person objects are two different objects (at least they have different address). I'm assuming that setWithArray:
is just doing a basic address compare but I don't understand why it is sometimes producing two objects like it should and sometimes producing only one.
Something I just tried was changing adam2
so that the first and last name were not exactly the same as adam1
. This seems to fix the error. Does this point to some sort of compiler optimization when the objects are logically the same?
isEqual:
as defined by theNSObject
protocol to compare objects; have you implemented it orhash
onPerson
? – Posture