两者都不。您应该使用NSFetchRequest
带有谓词的 an。您的模式可能会意外地破坏整个关系,这是非常昂贵的,并且不需要仅仅检查它是否包含一个对象。有一些方法可以小心谨慎,不要指责整个关系,但它很脆弱(搜索的微小变化会导致性能发生巨大变化),因此最好养成使用NSFetchRequest
而不是集合进行搜索的习惯。在这些情况下,我喜欢将 my 设置fetchLimit
为 1,因此一旦找到它,它就会停止查找。
为方便起见,您可能希望-containsFoo:
在托管对象上创建一个方法,这样您就不必到处编写获取逻辑。
您上面的两个解决方案略有不同。第一个测试集合中是否存在isEqual:
to的对象itemOfInterest
。您的第二个解决方案测试集合中是否存在与itemOfInterest
. 对于具有自定义isEqual:
逻辑的对象,这些可以返回不同的结果。这意味着解决方案 2 对于非核心数据收集可能会稍微快一些,但这是因为您实际上是在测试不同的东西,而不是因为对象枚举。(实际上,这只适用于小型收藏;见下文。)
为什么您认为解决方案 1 使用-objectEnumerator
?
正如@James Raybould 指出的那样,出于性能原因,您通常不应该尝试重写内置方法。如果isEqual:
解决方案 2 的某个版本比解决方案 1 更快,您会不会认为 Apple 会-containsObject:
使用解决方案 2 中的代码来实现?
实际上,底层CFSet
是作为散列实现的,因此检查包含是对数的而不是线性的。一般来说,对于具有合理散列函数的大集合,方案一会更快。请参阅CFSet.c中的代码。寻找CFSetContainsValue()
。当然,不能保证 CFSet 的实现保持不变,但它有助于理解在 Cocoa 中通常如何解决性能问题。