我认为NSCountedSet
在频率上计算了numB
和numC
两次因为它们具有相同的值,所以我创建了两个Fraction
个对象(未显示)类Fraction
,我将ivars
(numerator
,denominator
)设置为彼此相等,但countForObject:
将它们视为两个不同的对象并计算其频率各一个。 numA
和numB
指向内存中的不同位置但共享相同的值,并且两个Fraction
对象指向内存中的不同位置但共享相同的值。为什么Number
个对象被视为模糊不清,而不是Fraction
个对象?
#import <Foundation/Foundation.h>
#import "Fraction.h"
int main (int argc, char *argv[]) {
@autoreleasepool {
NSNumber *numA = [NSNumber numberWithInt: 1];
NSNumber *numB = [NSNumber numberWithInt: 2];
NSNumber *numC = [NSNumber numberWithInt: 2];
NSArray *array = [NSArray arrayWithObjects: numA, numB, numC, nil];
NSCountedSet *mySet = [[NSCountedSet alloc] initWithArray: array];
for (NSNumber *myNum in mySet) {
NSLog(@"Number: %i Frequency: %lu", [myNum intValue], [mySet countForObject: myNum]);
}
}
return 0;
}
2012-08-05 17:44:58.667 prog[1150:707] Number: 1 Frequency: 1
2012-08-05 17:44:58.669 prog[1150:707] Number: 2 Frequency: 2
答案 0 :(得分:1)
为了让NSCountedSet
和基金会的其余成员识别您的自定义类,您必须正确实施-isEqual:
和-hash
。默认情况下,它们比较指针,因此即使两个对象表示相同的数据,它们也永远不会相等。对于-isEqual:
类,Fraction
的简单实现可能如下所示:
- (BOOL)isEqual: (id)anObject {
#error Naive implementation. Do not use.
if (anObject == self) {
return YES;
} else if ([anObject isKindOfClass: [Fraction class]]) {
Fraction *reducedSelf = [self reducedFraction];
Fraction *reducedOther = [anObject reducedFraction];
if (reducedSelf.numerator == reducedOther.numerator && reducedSelf.denominator == reducedOther.denominator) {
return YES;
}
}
return NO;
}
- (NSUInteger)hash {
#error Naive implementation. Do not use.
Fraction *reducedSelf = [self reducedFraction];
return reducedSelf.numerator ^ reducedSelf.denominator;
}
请注意,这不允许您将Fraction
类的实例与NSNumber
的实例进行比较。由于-isEqual:
必须是可交换的,并且因为相等的对象必须具有相同的哈希值,因此您需要提供与NSNumber
兼容的实现(可能通过继承它并使用NSNumber
的实现。)