0

あるNSMutableArrayから別のNSMutableArrayへのオブジェクトのコピーを理解しようとしています。次の2つのシナリオを検討してください。1-クローンへのオリジナルのコピー。クローンの変更がオリジナルに影響します。2-クローズでの変更がオリジナルに影響を与えない場合に、オリジナルをクローンにコピーします。

まず、次のコードを使用して、最初にシナリオ#1を作成しようとしています。私が理解していることから、「mutablecopy」を使用せずに配列をコピーする場合、クローン配列は元の同じ文字列オブジェクトへのポインタを保持するだけです。では、クローンの最初の要素を別のオブジェクトに変更すると、元の要素の最初の要素が正しく変更されますか?...しかし、それは私が得ている結果ではありません。なんで?

実際のところ、mutablecopyを使用する場合

[self.cloneArray addObject:[[self.originalArray objectAtIndex:i] mutableCopy]];

同じ結果が得られます。私は混乱しています。

ArrayClass.h

@interface ArrayClass : NSObject {
    NSMutableArray *_originalArray;
    NSMutableArray *_cloneArray;
}

@property (nonatomic, retain) NSMutableArray *originalArray;
@property (nonatomic, retain) NSMutableArray *cloneArray;

ArrayClass.m

@synthesize originalArray = _originalArray;
@synthesize cloneArray = _cloneArray;

_originalArray = [[NSMutableArray alloc] initWithObjects: @"one", @"two", @"three", @"four", @"five", nil];
_cloneArray = [[NSMutableArray alloc] initWithCapacity:[self.originalArray count]];

for (int i=0; i<5; i++) {
    [self.cloneArray addObject:[self.originalArray objectAtIndex:i]];
}

// make change to the first element of the clone array
[self.cloneArray replaceObjectAtIndex:0 withObject:@"blah"];

for (int n=0; n<5; n++) {
    NSLog(@"Original:%@ --- Clone:%@", [self.originalArray objectAtIndex:n], [self.cloneArray objectAtIndex:n]);
}

..。

2011-03-27 03:23:16.637 StringTest[1751:207] Original:one --- Clone:blah
2011-03-27 03:23:16.638 StringTest[1751:207] Original:two --- Clone:two
2011-03-27 03:23:16.639 StringTest[1751:207] Original:three --- Clone:three
2011-03-27 03:23:16.642 StringTest[1751:207] Original:four --- Clone:four
2011-03-27 03:23:16.643 StringTest[1751:207] Original:five --- Clone:five
4

2 に答える 2

8

あなたはこの方法についてあまりにも一生懸命考えています。

Objective-Cでは、オブジェクトへの参照があります。は、を参照NSString *foo;する変数を定義するだけです。と言うと、オブジェクトが参照していたものへの参照があります。これ以上でもそれ以下でもありません。fooNSStringNSString *bar = foo;barfoo

AnNSArrayは、オブジェクト参照の単なるコレクションです。だから、あなたが言うなら:

NSArray *b = [NSArray arrayWithArray: a];

bとまったく同じオブジェクトのセットへの同じ参照をすべて含む配列を作成していますa。で参照されるオブジェクトを変更するとa、それはとまったく同じオブジェクトにbなり、変更が反映されます。

オブジェクトをコピーすると、元のオブジェクトと同じ内部状態を持つ新しいオブジェクトが作成されます。NSMutableString *foo = [barString mutableCopy];つまり、と言うときは、新しい文字列fooへの参照です。とは別のもの。barString

したがって...新しい配列を作成するとき、問題は、元の配列とまったく同じ内容を配列に含めるか、それとも変更可能な新しいオブジェクトのセットを配列に含めるかということです。

于 2011-03-27T07:47:15.470 に答える
5

あなたは何が起こっているのか誤解しています。このreplaceObjectAtIndex:withObject:呼び出しは、配列内のオブジェクトを変更するのではなく、配列自体を変更します。この行の後:

[self.cloneArray replaceObjectAtIndex:0 withObject:@"blah"];

クローン配列内のオブジェクトを置き換えましたが、元の配列はまったく変更していません。配列に配置NSStringしたオブジェクトを実際に変更した場合は、期待した動作が得られる可能性があります。ただし、例の元の配列に配置したオブジェクトは不変の文字列オブジェクトであるため、これらのオブジェクトを使用してこれを行うことはできませんそこに可変文字列を貼り付けた場合は、同じループを使用して配列を「クローン」し、次の行に沿って何かを実行しました。

[[self.cloneArray objectAtIndex:0] appendString:@"some junk to append"];

実際には、インデックス0の文字列オブジェクトを変更します。両方の配列に同じオブジェクトが含まれているため、「クローン配列のオブジェクトを変更して元の配列を変更する」動作を取得します。

于 2011-03-27T07:42:41.800 に答える