0

同じ値であるため、頻度が2回NSCountedSetカウントされるnumBと思ったので、クラスから2つのオブジェクト(図示せず)を作成し、それらの(、)を互いに等しくなるように設定しましたが、それらを2つの別個のオブジェクトとして扱い、カウントしました。それぞれの周波数。そして、メモリ内の異なる場所を指していますが、同じ値を共有しています。2つのオブジェクトは、メモリ内の異なる場所を指していますが、同じ値を共有しています。オブジェクトが不明瞭として扱われたのに、オブジェクトは扱われなかったのはなぜですか?numCFractionFractionivarsnumeratordenominatorcountForObject:numAnumBFractionNumberFraction

#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

カスタムクラスがFoundationの他のメンバーによって認識されるようにするには、正しくNSCountedSet実装する必要があります。デフォルトでは、ポインターを比較するため、2つのオブジェクトが同じデータを表している場合でも、2つのオブジェクトが等しく比較されることはありません。クラスのナイーブな実装は、おそらく次のようになります。-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 に答える