因此,Apple的文档说明了containsObject
:
此方法确定aObject是否存在于数组中 向每个数组的对象发送一个isEqual:消息(和 将anObject作为参数传递给每个isEqual:message)。
您可以找到这些文档here。
然而,我正在经历几乎完全相反的效果。我没有向我的数组中的每个对象发送isEqual:
,而是为数组中的每个对象发送isEqual:
消息。
例如,我有两个类:FlxSort
和FlxFieldKey
。 FlxSort
类包含一个字段键,如果它传递的isEqual:
对象与它所拥有的键匹配,我会覆盖FlxFieldKey
以返回true。理论上,这应该允许我检查数组中是否存在具有特定键的FlxSort
对象。但是,FlxFieldKey
不是(并且不应该)知道FlxSort
对象,因此如果在FlxSort
isEqual
中提供currentSorts
对象,它将始终返回false信息。因此,在下面的代码中,我希望isEqual:
中的每个对象都会为_avialableKeys
中的每个密钥发送_availableKeys
消息。相反,isEqual:
中的每个密钥都会发送NSMutableArray *keys = [NSMutableArray arrayWithCapacity:_avialableKeys.count];
NSArray *currentSorts = _sortGroup.sorts;
for (FlxFieldKey *key in _avialableKeys){
if (![currentSorts containsObject:key]){
[keys addObject:key];
}
}
消息。我已经使用日志记录和断点检查了这两个。
[NSArray containsObject:]
我在这里错过了什么吗?
更新
即使我在询问containsObject
,我也得到了很多关于我实现非对称平等的反馈。所以我想澄清一下,我的实施是出于好奇而产生的实验。原始代码根本没有使用NSMutableArray *keys = [NSMutableArray arrayWithCapacity:_avialableKeys.count];
NSArray *currentSorts = _sortGroup.sorts;
for (FlxFieldKey *key in _avialableKeys){
BOOL found = NO;
for (FlxSort *sort in currentSorts){
if ([sort.key isEqual:key]){
found = YES;
break;
}
}
if (!found){
[keys addObject:key];
}
}
:
containsObject
我很好奇我是否可以装isEqual:
在上述情况下工作。当然,正如一些人所指出的那样,创建不对称平等是一个坏主意,并直接反对Apple的建议。我可以更改FlxFieldKey
中的FlxSort
方法以考虑hash
个对象,这将恢复两个类之间的对称相等...等等。你仍然可以得到A == B,A == C,但是B!= C.而且仍然存在{{1}}问题(它们需要相同)。
让我重申一下:你不想这样做(非对称平等)。至少,不在生产代码中。我只是在这里看到我 可以 做什么,而不是我 应该 做什么。我承认,在原始问题中不澄清这一点是不负责任的,因为经验不足的开发人员可能会认为这种实现是可行的。我为此道歉。
是的,一旦我能鼓起勇气再次进入Apple的bug记者,我可能会在Radar报告一个文档错误......
答案 0 :(得分:1)
我不知道这是实际发生的事情,但实施containsObject:
为(松散地):
for( id containedObj in self ){
if( [testObj isEqual:containedObj] ){
return YES;
}
}
表示testObj
的{{1}}实现可以直接缓存和调用,而不是每次都通过isEqual:
调度的消息。因为objc_msgSend()
s可能是异质的,所以如果比较是相反的,那么就不可能缓存每个调用,就像文档所说的那样。
那里有一个微小的性能提升,可以为大型阵列辩护。
你应该提交一个doc bug,尽管正如Rob Napier指出的那样,如果你让平等不对称,这只是一个问题,这本身就是一个有问题的想法。
答案 1 :(得分:0)
你是对的,这是实施和文档之间的差异,你应该file a bug on radar。
然而,它的目的是在您的实现中突出显示设计问题。
比较的顺序真的不应该是平等
[objectA isEqual:objectB] == [objectB isEqual:objectA];
应该永远是真的,除非你故意想遇到麻烦。
那就是说我相信NSSet
更适合于那种任务,因为containsObject:
操作在恒定时间内执行,而NSArray
操作则是hash
。 }。在这种情况下,您还需要覆盖{{1}}方法。