NSSet 包含具有被覆盖的 isEqual 的对象
NSSet containing objects with overwritten isEqual
在我的 class 中,我覆盖了 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
实际上是一个散列 table,如果它包含散列值,可以快速检查它...这就是我们所知道的
但是,让我们想象一下这段代码
NSArray * instancesToCheck = ...;
NSArray * allInstances = ...;
for (MyClass * instance in allInstances) {
if ([instancesToCheck containsObject:instance]) {
// do smth
}
}
我想 "optimize" 这个(使用 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 但指针比较==NO)?
当我查看文档时,我发现 containsObject 调用了 isEqual,因此无论如何它都必须遍历所有对象
将 NSSet 与对象一起使用时,覆盖 isEqual 对性能有何影响?变成NSSet那么效率低了?
Does the second code provide any performance benefit at all
当然可以。数组必须循环检查每个对象的数组。一个集合或多或少立即知道一个对象是否被包含,因为它是一个散列table。事实上,这种东西正是集合 for.
您必须覆盖 hash
,如果您覆盖 isEqual:
否则可能会破坏功能并且可能无法按预期运行
被视为 "equal" 的两个对象必须 return 具有相同的哈希值。
- (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];
}
在我的 class 中,我覆盖了 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
实际上是一个散列 table,如果它包含散列值,可以快速检查它...这就是我们所知道的
但是,让我们想象一下这段代码
NSArray * instancesToCheck = ...;
NSArray * allInstances = ...;
for (MyClass * instance in allInstances) {
if ([instancesToCheck containsObject:instance]) {
// do smth
}
}
我想 "optimize" 这个(使用 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 但指针比较==NO)?
当我查看文档时,我发现 containsObject 调用了 isEqual,因此无论如何它都必须遍历所有对象
将 NSSet 与对象一起使用时,覆盖 isEqual 对性能有何影响?变成NSSet那么效率低了?
Does the second code provide any performance benefit at all
当然可以。数组必须循环检查每个对象的数组。一个集合或多或少立即知道一个对象是否被包含,因为它是一个散列table。事实上,这种东西正是集合 for.
您必须覆盖 hash
,如果您覆盖 isEqual:
否则可能会破坏功能并且可能无法按预期运行
被视为 "equal" 的两个对象必须 return 具有相同的哈希值。
- (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];
}