0

我认为这NSCountedSet计数numBnumC频率的两倍,因为它们具有相同的值,所以我Fraction从我的类中创建了两个对象(未显示)Fraction,并且我将它们的ivars( numerator, denominator) 设置为彼此相等,但将countForObject:它们视为两个不同的对象并计数它们的频率各为一个。numAnumB指向内存中的不同位置但共享相同的值,并且两个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
4

1 回答 1

1

为了让您的自定义类被NSCountedSetFoundation 的其余部分识别和识别,您必须-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的实现。)

于 2012-08-05T22:40:42.787 回答