views:

167

answers:

1

Hi, I have a simple question regarding xcode coding but don't know why things are not performing as I think. I have an array of objects (custom objects). I just want to check if this one is within the array. I used the following code:

NSArray *collection = [[NSArray alloc] initWithObjects:A, B, C, nil]; //A, B, C are custom "Item" objects
Item *tempItem = [[Item alloc] initWithLength:1 width:2 height:3];  //3 instance variables in "Item" objects
if([collection containsObject:tempItem]) {
    NSLog(@"collection contains this item");
}

I suppose the above checking will give me a positive result but it's not. Further, I checked whether the objects created are the same.

NSLog(@"L:%i W:%i H:%i", itemToCheck.length, itemToCheck.width, itemToCheck.height);
for (int i = 0, i < [collection count], i++) {
    Item *itemInArray = [collection objectAtIndex:i];
    NSLog(@"collection contains L:%i W:%i H:%i", itemInArray.length, itemInArray.width, itemInArrayheight);
}

In the console, this is what I got:

L:1 W:2 H:3
collection contains L:0 W:0 H:0
collection contains L:1 W:2 H:3
collection contains L:6 W:8 H:2

Obviously the tempItem is inside the collection array but nothing shows up when I use containsObject: to check it. Could anyone give me some direction which part I am wrong? Thanks a lot!

+5  A: 

The documentation for [NSArray containsObject:] says:

This method determines whether anObject is present in the receiver by sending an isEqual: message to each of the receiver’s objects (and passing anObject as the parameter to each isEqual: message).

The problem is that you are comparing references to objects rather than the values of the objects. To make this specific example work, you will either need to send [collection containsObject:] an instance of a variable it contains (e.g. A, B, or C), or you will need to override the [NSObject isEqual:] method in your Fruit class.

This is what your isEqual method might look like:

- (BOOL)isEqual:(id)other {
    if (other == self)
      return YES;
    if (!other || ![other isKindOfClass:[self class]])
      return NO;
    if (self.length != other.length || self.width != other.width || self.height != other.height)
      return NO;
    return YES;
}

For a better implementation, you may want to look at this question.

Senseful
Oh, sorry, just a typo for "Fruit", it should be "Item". Do you mean comparing custom class objects by containsObject: does not work?
Anthony Chan
It does work, it just be default compares using a reference to your custom object. If you want to make `tempItem` equal to `A` in your example above, you will need to simply create that `isEqual` method on your class.
Senseful
@Anthony, think of it this way: How could `NSObject`, which provides the default comparison, know how equality is defined for your custom classes? Which properties should it take into consideration and which not?
Georg Fritzsche
ok, I got the idea. Sorry for this silly question as I'm still new to computer programming. Million thanks to eagle and Georg! You guys are so great! I'll try that. Thanks for your help again!
Anthony Chan