混淆了清晰的对象 [英] Confusion with distinct and indistinct object

查看:106
本文介绍了混淆了清晰的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为NSCountedSet计数numBnumC的频率是两次,因为它们具有相同的值,所以我从类Fraction创建了两个Fraction对象(未显示),并设置了它们的ivars(numeratordenominator)彼此相等,但是countForObject:将它们视为两个不同的对象,并将它们的频率计为一个. numAnumB指向内存中的不同位置,但共享相同的值,而两个Fraction对象指向内存中的不同位置,但共享相同的值.为什么将Number对象视为模糊的,而将Fraction对象视为模糊的?

I thought that NSCountedSet counted numB and numC twice in the frequency because they had the same value, so I created two Fraction objects (not shown) from my class Fraction, and I set their ivars (numerator, denominator) to equal each others but the countForObject: treated them as two distinct objects and counted their frequencies as one each. numA and numB pointed to different places in memory but share the same value, and the two Fraction objects pointed to different places in memory but shared the same value. Why were the Number objects treated as indistinct, but not the Fraction objects?

#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

推荐答案

为使您的自定义类被NSCountedSet和Foundation的其余部分识别,您必须正确实现-isEqual:-hash.默认情况下,它们比较指针,因此即使两个对象表示相同的数据,它们也永远不会比较相等.对于Fraction类的-isEqual:幼稚实现可能看起来像这样:

In order for your custom class to be recognized by NSCountedSet and by the rest of Foundation, you must implement -isEqual: and -hash correctly. By default, they compare pointers, so two objects will never compare equal even if they represent the same data. A naïve implementation of -isEqual: for a Fraction class would probably look like this:

- (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的实现.)

Note that this would not allow you to compare instances of your Fraction class against instances of NSNumber. Because -isEqual: must be commutative and because equal objects must have the same hash value, you would need to provide an implementation that was compatible with NSNumber (probably by subclassing it and using NSNumber's implementations.)

这篇关于混淆了清晰的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆