0

fracBによって作成された不変Fractionオブジェクトを参照しているときに、なぜ変更が許可されているのか疑問に思いましたNSCopyWithZone:

#import <Foundation/Foundation.h>

@interface Fraction : NSObject <NSCopying>
@property int numerator, denominator;

-(void) set: (int) n over: (int) d;
-(Fraction *) initWithValues: (int) n over: (int) d;

@end

@implementation Fraction
@synthesize numerator, denominator;

-(Fraction *) initWithValues:(int)n over:(int)d {
    self = [super init];

    if (self) 
        [self set:n over:d];

    return self;
}

-(void) set: (int) n over:(int)d {
    numerator = n;
    denominator = d;
}

-(Fraction *) copyWithZone:(NSZone *)zone {
    Fraction *copied = [[Fraction allocWithZone: zone] init];

    [copied set:numerator over:denominator];

    return copied;
}

@end

#import "Fraction.h"
#import <Foundation/Foundation.h>

int main (int argc, char *argv[])  
{  
    @autoreleasepool {  
        Fraction *fracA = [[Fraction alloc] initWithValues:5 over:5];
        Fraction *fracB = [[Fraction alloc] init];

        fracB = [fracA copy];
        [fracB set:2 over:2];

        NSLog(@"%@", fracB);
    }
    return 0;  
}

2012-08-07 20:01:04.248 prog[1972:707] 2/2
4

2 に答える 2

1

可変性は、インスタンスの作成に使用されるメソッドではなく、フレームワークではなく、言語ではなく、クラスによって定義されます。クラスを不変にすることができるのは、独自のコードだけです。

copyもっと簡単に言えば、クラスがいくつかのプロパティにsetterメソッドを提供している場合は、またはの使用に関係なく、そのプロパティを設定できますmutableCopy

NSMutableCopyingドキュメント(メソッドが来るところ)mutableCopyが言うように、

「不変と可変」の区別を定義するクラスのみがこのプロトコルを採用する必要があります。

独自のクラスでこの区別が必要な場合は、 /または/の型で2つのクラスを作成するのが最善の方法です。ここで、可変バージョンは他のサブクラスです。だからあなたは持っているかもしれませんそして。NSArrayNSMutableArrayNSStringNSMutableStringFractionMutableFraction

メソッドだけMutableFractionがありset:over:ます; Fractionインスタンスでは、オブジェクトの作成時にこれらの値を設定する必要があります。次に、を実装mutableCopyFractionてのインスタンスを返しますMutableFraction(の実装はそのcopyままにしておくことができます)。

于 2012-08-08T00:23:31.503 に答える
1

クラスは変更可能だからです。Objective-Cは、あなたがそれが不変であることを意味していることを知りません。言語は、不変性が何を意味するのかさえ知りません。クラスにミューテーター(状態または値を変更するメソッド)がある場合、それらを削除しないでくださいNSCopying

クラスを本当に不変にしたい場合は、ミューテーター(。)を削除します-set:over:。可変オブジェクトと不変オブジェクトを区別したい場合は、サブクラスを作成し、そのサブクラスMutableFractionでのみ公開-set:over:します。

于 2012-08-08T00:24:14.813 に答える