4

I've read through many SO posts before asking this question and I'm guessing this answer was in there somewhere, but I didn't see it. I'm new to Objective-C and I'm trying to do a (seemingly) simple action that I can't figure out.

The general idea is that I have an NSArray filled with objects (specifically of type UIImageView). I want to copy that array, which I've done a number of ways (all successful).

After a copy it, I now have two arrays. I want to modify an object, say at index 2, ONLY in the copy.

So far it seems like, because the copy is merely copying the reference (or pointer), changing the object at index 2 will change it in both the copy and the original.

Does that make sense?

NSArray *originalArray = @[object1, object2];

Ways I've tried copying this array, so that I can achieve what I want:

NSMutableArray *originalArrayCopy = [NSMutableArray arrayWithArray:originalArray];

NSArray *originalArrayCopy = [originalArray copy];

NSMutableArray *originalArrayCopy = [[NSMutableArray alloc] initWithArray:originalArray];

And it seems that in each case, modifying an object from the copy also modifies it in the original.

NOTE: While NSArray is obviously immutable, the objects within my original array are mutable.

4

4 に答える 4

12

配列の要素がNSCopyingプロトコルに準拠している場合は、次のことができます。

NSMutableArray *copy = [[NSMutableArray alloc] initWithArray:originalArray copyItems:YES];

これにはcopy、元の配列の各要素に送信し、コピーを新しい配列に格納する効果があります。

copyメッセージを受信したときに各要素が新しい変更可能なコピーを返す場合、これは問題ありません。ただし、いくつかの Foundation クラス (NSMutableArrayや などNSMutableString) は、メッセージを受信したときに不変のコピーを返しcopyます。要素がそのようなクラスに属している場合は、mutableCopy代わりにメッセージを送信する必要があります。

それを行うための組み込みの公開メッセージはありません。次のように手動で行うことができます。

NSMutableArray *copy = [[NSMutableArray alloc] initWithCapacity:originalArray.count];
for (id element in originalArray) {
    [copy addObject:[element mutableCopy]];
}
于 2013-05-31T21:39:18.450 に答える
1

コピーしようとしているオブジェクトが NSCoding プロトコルを実装している限り

(void)encodeWithCoder:(NSCoder *)encoder;
(id)initWithCoder:(NSCoder *)decoder;

この方法で、任意のオブジェクトのディープ コピーを作成できます

NSArray *originalArray = @[object1, object2];
NSMutableArray *deepCopy = [NSkeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject: originalArray]];
于 2013-05-31T22:07:59.040 に答える
0

はい、配列のみをコピーします。コピーした配列は引き続き同じオブジェクトを参照します。

含まれているすべてのオブジェクトを一度にコピーできるとは思いません (または方法がわかりません)。元の配列内のオブジェクトを反復処理し、各オブジェクトをコピーして、そのコピーを新しく作成された元々空の可変配列に追加する必要があると思います。これらのオブジェクトをどのようにコピーするかは、これらのオブジェクトの性質とコピーの目的に大きく依存します。

はい、不変配列内のオブジェクトも不変でなければならない理由はありません。

于 2013-05-31T21:37:21.663 に答える