覆盖isEqual:方法但从数组中删除对象时不会调用它

时间:2011-12-25 06:36:10

标签: objective-c inheritance nsarray foundation nsobject

我正在使用xCode 4.2,并阅读“Objective in Objective C 2.0”一书

有一项练习涉及从isEqual:课程实施NSObject方法。

本书说,isEqual:方法在调用removeObjectIdenticalTo:类的NSArray方法时触发。 removeObjectIdenticalTo:最终会向所有阵列成员发送isEqual:消息。

当我尝试在我的班级isEqual:中实现此AddressCard方法时,我使用removeObjectIdenticalTo:,传递一个AddressCard类实例的对象,但是,我的isEqual:方法没有被调用。虽然我只是明确地在isEqual:的实例上使用AddressCard方法,但它确实有效。

以下是AddressCard.m文件中的isEqual:方法

-(BOOL)isEqual: (id)object {
    NSLog(@"I got called");
    return NO;
}

在AddressBook.m中触发此代码时

-(void) removeCard: (AddressCard *) theCard {
    [book removeObjectIdenticalTo: theCard];
}

不调用上面列出的isEqual:方法。

我觉得我错过了一些重要的东西,但是从我读过的所有内容中我知道,我认为isEqual:必须被调用,除非removeObjectIdenticalTo:不再涉及它。

我也在.h文件中定义了所有相应的方法。

2 个答案:

答案 0 :(得分:8)

正如您所猜测的那样,removeObjectIdenticalTo:不会调用isEqual:,因为它只使用对象地址来检查相等性。

但是removeObject:会调用isEqual:,因此您很可能会想要这样做。

答案 1 :(得分:6)

听起来这本书出错了。

NSMutableArray和其他集合有一些类似的方法,如removeObject:removeObjectIdenticalTo:,其含义有重要差异。

第一个测试集合中对象的是否与传入对象的值相同。为此,数组在数组中的每个对象上调用isEqual:。这允许每个类为自己定义与另一个对象的“相等”意味着什么,正如您为AddressCard类所做的那样。有关removeObject:的详细信息,请参阅its documentation

  

此方法使用indexOfObject:来定位匹配[...]因此,匹配是根据对象对isEqual:消息的响应确定的。

...IdenticalTo:方法处理对象内存中的实际身份。它们检查传入对象的地址是否与集合中的任何地址相同。数组可以在不调用该对象的任何方法的情况下找到对象的地址;此处未使用isEqual:。同样,这在docs

中说明
  

此方法使用indexOfObjectIdenticalTo:方法定位匹配[...]因此,匹配是使用对象地址确定的。

一般来说,您需要removeObject:removeObjectIdenticalTo:更频繁,因为它的含义与您希望执行的操作最匹配:选择为的对象与提供的对象相同。