Wie*_*nke 5 core-data objective-c nsset
我需要确定一个对象是否包含在Core Data to-many关系(这是一个NSSet)中,并且我试图决定哪两个解决方案更好:
解决方案1)
if ([managedObject.items containsObject:itemOfInterest])
return …
Run Code Online (Sandbox Code Playgroud)
解决方案2)
for (NSManagedObject *item in managedObject.items)
if ([item == itemOfInterest])
return …
Run Code Online (Sandbox Code Playgroud)
解决方案1更简洁,但NSSet Class Ref表示快速枚举的性能优于NSSet的objectEnumerator.它是否也比containsObject更好?
Rob*_*ier 20
都不是.你应该使用NSFetchRequest
带谓词的.您的模式可能会意外地破坏整个关系,这非常昂贵,并且不需要仅检查它是否包含一个对象.有一些方法要小心,不要错过整个关系,但它很脆弱(搜索的微小变化导致性能发生巨大变化),因此最好养成使用NSFetchRequest
而不是搜索集合的习惯.我喜欢fetchLimit
在这些情况下将我设置为1,所以一旦找到它,它就会停止寻找.
为方便起见,您可能希望-containsFoo:
在托管对象上创建一个方法,这样就不必在整个地方编写获取逻辑.
您上面的两个解决方案略有不同.第一个测试是否有集合中的对象isEqual:
来itemOfInterest
.您的第二个解决方案测试集合中是否存在与该存储位置相同的对象itemOfInterest
.对于具有自定义isEqual:
逻辑的对象,这些可以返回不同的结果 这意味着对于非核心数据集合,解决方案2可能稍微快一些,但这是因为您实际上正在测试不同的东西,而不是因为对象枚举.(实际上,这仅适用于小型馆藏;请参见下文.)
您为什么相信解决方案1使用-objectEnumerator
?
正如@James Raybould指出的那样,出于性能原因,通常不应该尝试重写内置方法.如果isEqual:
解决方案2 的版本比解决方案1快,您认为Apple不会-containsObject:
使用解决方案2中的代码实现吗?
实际上,底层CFSet
是作为哈希实现的,因此检查包含是对数而不是线性.一般来说,对于具有合理散列函数的大集合,解决方案1将更快.请参阅CFSet.c中的代码.寻找CFSetContainsValue()
.当然,CFSet的实现并不保证保持不变,但它有助于理解Cocoa中通常如何解决性能问题.
归档时间: |
|
查看次数: |
4886 次 |
最近记录: |