在我的班级中,我会覆盖isEqual
@interface MyClass : NSObject
@property (nonatomic, strong) NSString * customID;
@end
我覆盖了isEqual,因此只检查customID
的相等性- (BOOL)isEqual:(id)object {
if ([object isKindOfClass:[MyClass class]]) {
if (self.customID == nil) {
return NO;
}
return [self.customID isEqual:[object customID]];
}
return [super isEqual:object];
}
现在NSSet
实际上是一个哈希表,如果它包含一个哈希值,那么可以快速检查...这就是我们所知道的事情
但是,让我们想象一下这段代码
NSArray * instancesToCheck = ...;
NSArray * allInstances = ...;
for (MyClass * instance in allInstances) {
if ([instancesToCheck containsObject:instance]) {
// do smth
}
}
我想用这个“优化”(使用NSSet进行成员资格测试)
NSArray * instancesToCheck = ...;
NSArray * allInstances = ...;
NSSet * instancesToCheckAsSet = [NSSet setWithArray:instancesToCheck];
for (MyClass * instance in allInstances) {
if ([instancesToCheckAsSet containsObject:instance]) {
// do smth
}
}
第二个代码是否提供任何性能优势(假设在创建它的数组中没有重复,并且instancesToCheck包含不同的指针,但是一些对象具有相同的customID,使isEqual == YES但指针比较==否)?
当我查找文档时,我发现,containsObject调用isEqual,所以它必须遍历所有对象
将NSSet与对象一起使用会有什么影响,覆盖isEqual?那么NSSet效率会降低吗?
答案 0 :(得分:2)
第二个代码是否提供了所有性能优势
绝对。数组必须在数组中循环检查每个对象。一个集合或多或少知道即时是否包含对象,因为它是一个哈希表。实际上,这类事物恰好是 for 的集合。
答案 1 :(得分:1)
你必须覆盖hash
,否则覆盖isEqual:
否则可能会破坏功能,而事情可能无法按预期运行
两个被认为是"相等的对象"必须返回相同的哈希值。
- (BOOL)isEqual:(id)object {
if ([object isKindOfClass:[MyClass class]]) {
if (self.customID == nil) {
return NO;
}
return [self.customID isEqual:[object customID]];
}
return [super isEqual:object];
}
// MUST overwrite hash
- (NSUInteger)hash {
return [self.customID hash];
}