Pergunta

Estou tentando entender a cópia de objetos de um NSMutableArray para outro.Considere os 2 cenários a seguir:1 - copiar o original para clonar onde as alterações no clone afetarão o original.2 - copiar o original para clonar onde as alterações no fechamento NÃO afetarão o original.

Primeiro, estou tentando produzir o cenário nº 1 primeiro com o código a seguir.Pelo que entendi, ao copiar o array sem usar 'mutablecopy', o array clone apenas manterá o ponteiro para os mesmos objetos de string no original.Então se eu mudasse o primeiro elemento do clone para um objeto diferente, o primeiro elemento do original também mudaria, certo?...mas esse não é o resultado que estou obtendo.Por que?

Na verdade, quando eu uso mutablecopy

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

Eu obtenho o mesmo resultado.Estou confuso.

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
Foi útil?

Solução

Você não entende o que está acontecendo.O replaceObjectAtIndex:withObject: call não está modificando objetos no array, está modificando o próprio array.Após esta linha:

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

você substituiu o objeto em seu array clone, mas não alterou o array original.Se você realmente modificou o NSString contestar você colocar nas matrizes, você poderá obter o comportamento esperado.Você não vai ser capaz de fazer isso com os objetos que você colocou na matriz original em seu exemplo, já que eles são objetos de string imutáveis.Se você colocou strings mutáveis ​​​​lá, usou o mesmo loop para 'clonar' seu array e, em seguida, fez algo como:

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

você realmente modificaria o objeto string no índice 0.Como ambas as matrizes ainda contêm o mesmo objeto, você obteria o comportamento 'modificar a matriz original alterando os objetos na matriz clone'.

Outras dicas

Você está pensando muito sobre isso.

No Objective-C, você tem referências a objetos.Um NSString *foo; simplesmente define uma variável foo que se refere a um NSString.Se você diz NSString *bar = foo;, então bar terá uma referência a qualquer objeto foo estava se referindo.Nem mais nem menos.

Um NSArray é apenas uma coleção de referências de objetos.Então, se você disser:

NSArray *b = [NSArray arrayWithArray: a];

Você está criando uma matriz b que contém todas as mesmas referências ao mesmo conjunto de objetos que a.Se você modificar um objeto referido por a, esse será exatamente o mesmo objeto em b e a modificação será refletida.

Quando você cópia de um objeto, você está criando um novo objeto que possui o estado interno idêntico ao original.Ou sejaquando voce diz NSMutableString *foo = [barString mutableCopy];, então foo é uma referência a um novo corda;um diferente do que barString.

Então...ao criar um novo array, a questão é: você deseja que o array contenha exatamente o mesmo conteúdo do array original ou deseja que ele contenha um novo conjunto de objetos que você pode modificar?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top