web-dev-qa-db-ja.com

ディープコピーとシャローコピー

投稿からディープコピーとシャローコピーの違いの答えを読みました ディープコピーとシャローコピーの違いは何ですか? 。今、私たちが浅いコピーを作ったとき、私はいくつかの疑問を抱きました

 newArray = [NSmutableArray arrayWithArray:oldArray];

新しい配列はoldArrayを指します。 (図から)。 newArrayからオブジェクトを削除するとどうなりますか?図からわかるように、oldArrayからも同じ要素を削除する必要があります!!!どうやら

newArray = oldArrayは浅いコピーであり、newArray = [NSmutableArray arrayWithArray:oldArray];はディープコピーです。正しいですか?

16
rakeshNS

newArary = oldArrayはまったくコピーではありません。まったく同じメモリ位置を指す2つのポインタができあがります。

newArray = [NSMutableArray arrayWithArray:oldArray];は浅いコピーです。最終的に2つの異なる配列になるため、一方の配列からアイテムを削除または追加しても、もう一方の配列には影響しません。ただし、2つの配列のitemsは同一です。 oldArrayの最初の要素がNSMutableDictionaryであり、それにキーを追加した場合、newArrayの最初の要素にもその変更が表示されます(これら2つ以降)オブジェクトは同じです)。

ディープコピーを実行するには、新しい配列を作成する必要があり、新しい配列の各要素は、古い配列の対応する要素のディープコピーになります。 (はい、その定義は再帰的です)。

41
yuji

まず第一に、NSArrayにはディープコピー機能がありません。ただし、以下を実行することにより、ディープコピー機能を作成できます。

@interface NSArray(deepCopy)

-(NSArray *) deepCopy;

@end

@implementation

-(NSArray *) deepCopy
{
    NSMutableArray *ret = [NSMutableArray array];

    for (id val in self)
    {
        if ([val conformsToProtocol:@protocol(NSCopying)])
        { 
            [ret addObject:[val copy]];
        }
        else
        {
           [ret addObject:val];
        }
    }

    return ret;
}

@end 

第二に、newArray = oldArray配列をコピーしません。単にnewArrayoldArrayが指す配列を指すようにします。

第3、 +arrayWithArray:は配列の浅いコピーを実行します。つまり、個々のオブジェクトはコピーされません。

11

[[NSArray alloc] initWithArray:arraytoBeCopied copyItems:YES];に電話することもできます

2
Genki