Copia profunda y copia superficial de IOS
1. ¿Copia superficial
? La copia superficial es una copia de la dirección de memoria, por lo que el puntero del objeto de destino y el objeto de origen apuntan al mismo espacio de memoria. Cuando la memoria está dañada, es necesario redefinir varios punteros a esa memoria antes de poder utilizarlos; de lo contrario, se convierten en punteros salvajes.
? Una copia superficial copia el puntero al objeto original para que el recuento de referencias del objeto original sea 1. Puede entenderse como la creación de un nuevo puntero que apunta al objeto original, pero no crea un objeto nuevo.
2. ¿Copia profunda
? La copia profunda se refiere a copiar el contenido específico del objeto y la dirección de memoria la asigna usted mismo. Después de copiar, aunque los valores de los dos objetos son los mismos, las direcciones de memoria son diferentes y los dos objetos no se afectan ni interfieren entre sí.
Una copia profunda es una copia de un nuevo objeto con el mismo valor pero una dirección de memoria completamente diferente, que es independiente del objeto original después de su creación.
3. Resumen:
La copia profunda es una copia del contenido y la copia superficial es una copia de puntero. La diferencia esencial es:
¿Quieres abrir una nueva dirección de memoria?
¿Afectará el recuento de referencias de la dirección de memoria?
2. ¿Análisis de ejemplo
? En iOS, la copia profunda y la copia superficial son más complejas e implican la copia y la copia mutable de objetos contenedores y no contenedores, mutables e inmutables. Analicemos varios ejemplos uno por uno:
1. ¿Copias y copias mutables de objetos que no pertenecen a la colección
? 1.1 ¿Objeto inmutable NSString?
-(void)nomutablenstringtest
{
ns string * str 1 = @"test 001";
NSMutableString * str 2 =[str 1 copy];
//copy devuelve un objeto inmutable, str2 no se puede modificar, por lo que fallará.
//[str 2 appendString: @"test"];
NSMutableString * str 3 =[str 1 copia mutable];
[str 3 appendString :@"modificar"];
NSLog(@"str1: p-@\r\n",str 1,str 1);
NSLog(@"str2: p - @\r\n", str 2, str 2);
NSLog(@"str3: p-@\r\n", str 3, str 3);
}
? Resultado de impresión:
2017-07-2018:02:10.642
Análisis: las direcciones str1, str2 son iguales pero diferentes de las direcciones str3. La copia de NSString es una copia superficial. y el objeto devuelto por la copia Es un objeto inmutable; MutableCopy es una copia profunda.
? 1.2 Objeto mutable NSMutableString
-(void) prueba de cadena variable
{
NSMutableString * mstr 1 = [cadena NSMutableString con cadena: @"test 002 "] ;
NSMutableString * mstr 2 =[mstr 1 copy];
//copy devuelve un objeto inmutable, mstr2 no se puede modificar, por lo que fallará.
//[str 2 appendString: @"test"];
NSMutableString * mstr 3 =[mstr 1 copia mutable];
[mstr 3 appendString :@"modificar"];
NSLog(@"mstr1: p-@\r\n",mstr 1,mstr 1);
NSLog(@"mstr2: p -@\r\n",mstr 2,mstr 2);
NSLog(@"mstr3: p-@\r\n",mstr 3,mstr 3);
}
Imprimir resultados:
2017-07-2018: 14:35.789
Análisis: Las direcciones de mstr1, mstr2 y mstr3 son diferentes. La copia del objeto NSMutableString y la copia mutable son copias profundas y el objeto devuelto por la copia es un objeto inmutable.
2. Copia y copias mutables de objetos de colección
2.1 Objeto inmutable NSArray
-prueba de matriz mutable (void)
{
NSArray * arry 1 =[[NSArray alloc]initWithObjects:@"valor 1",@"valor 2",nil];
NSArray * arry 2 =[arry 1 copia] ;
NSArray * arry 3 =【arry 1 copia mutable】;
NSLog(@"arry1: p-@\r\n",arry 1,arry 1 );
NSLog(@"arry2: p-@\r\n",arry 2,arry 2);
NSLog(@"arry3: p-@\r\ n", arry 3,arry 3);
}
Resultado de impresión:
王[1502:194476]arry 1:0x 60800003 b480-(
Valor 1,
Valor 2
) 2065438 2018:33:53.708
Valor 1,
Valor 2 p>
王【1502:194476】arry 3: 0x 60800004 CD 20- (
Valor 1,
Valor 2
)
Análisis: Las direcciones de arry1 y arry2 son las mismas, pero las direcciones de arr3 son diferentes. La copia de NSArray es una copia superficial y el objeto devuelto por la copia es un objeto inmutable.
? 2.2 Objeto mutable NSMutableArray
-(void) NSMutableArrayTest
{
NSMutableArray * casarse 1 = [[NSMutableArray alloc] initWithObjects: @"valor 1", @ "valor 2", nil】;
NSMutableArray * casarse 2 =【casarse 1 copia】;
//copiar devuelve un objeto inmutable. Married2 no se puede modificar y por lo tanto fallará.
//[casarse 2 agregar objeto: @"valor 3"];
NSMutableArray * casarse 3 =[casarse 1 copia mutable];
NSLog( @"casarse1: p-@\r\n",casarse 1,casarse 1);
NSLog(@"casarse2: p-@\r\n",casarse 2,casarse 2);
NSLog(@"marry3: p-@\r\n",casar 3,casar 3);
}
Imprimir resultados:
Wang [1577:204641] María 1: 0x600000048d60-(
Valor 1,
Valor 2
2065438 2018:55:43.244
Valor 1,
Valor 2
Wang [1577:204641] casarse 3: 0x 6000000494 B0-(
Valor 1,
Valor 2
)
Análisis: las direcciones de casarse1, casarse2 y marr3 son diferentes. La copia del objeto NSMutableArray y la copia mutable son copias profundas y el objeto devuelto por copia. es un objeto inmutable.
Es importante tener en cuenta que para los objetos mutables de la clase de colección, la copia profunda no es una copia profunda estricta, sino solo una copia profunda de un solo nivel, es decir, el valor. El elemento almacenado en la memoria (es decir, el valor en la matriz) sigue siendo el hogar del valor del elemento de la matriz, no hay otras copias), esto se denomina copia profunda de un solo nivel.
Por ejemplo:
-(void)singlensmabularytest
{
NSMutableArray * casarse 1 =[[NSMutableArray alloc]init];
NSMutableString * mstr 1 =[[NSMutableString alloc]init withstring:@"value 1"];
NSMutableString * mstr 2 =[[NSMutableString alloc]init constring:@"value 2 "];
[casarse 1 agregar objeto: mstr 1];
[casarse 1 agregar objeto: mstr 2];
NSMutableArray * casarse 2 = [ casarse con 1 copia】;
NSMutableArray * casarse con 3 =【casarse con 1 copia mutable】;
NSLog(@"casarse1: p-@\r\n",casarse con 1, casarse 1);
NSLog(@"casarse2: p-@\r\n",casarse2,casarse2);
NSLog(@"casarse3: p-@\r \ n",casarse con 3,casarse con 3);
NSLog(@"dirección del elemento de matriz: valor 1: valor p2: p\r\n",casarse con 1[0],casarse con 1[1] );
NSLog (@"Dirección del elemento de matriz: valor 1: valor p 2: p\r\n", casarse con 2[0], casar con 2[1]);
NSLog(@"Dirección del elemento de matriz: valor 1: valor p 2: p\r\n", casarse con 3[0], casar con 3[1]);
NSLog(@" \ r\n-después de modificar el valor original);
[mstr 1 append format: @"AAA"];
NSLog(@"marry1: p-@\r\n ",casarse 1,casarse 1);
NSLog(@"casarse2: p-@\r\n",casarse 2,casarse 2);
NSLog(@"casarse3 :p-@\r\n",casarse 3,casarse 3);
NSLog(@"dirección del elemento de matriz: valor 1: valor p2: p\r\n",casarse 1[0 】, casarse con 1【1】);
NSLog(@"Dirección del elemento de matriz: valor 1: valor p 2: p\r\n", casarse con 2[0], casarse con 2[1]
NSLog (@"Dirección del elemento de matriz: valor 1: valor p 2: p\r\n", casar con 3[0], casar con 3[1]); p>}
Resultado de impresión:
Wang [1750: 230132] casarse 1: 0x 60800004 ae00-(
Valor 1,
Valor 2
Wang [1750: 230132] casarse 2: 0x 6080000023 f00-(
Valor 1,<
/p>
Valor 2
Wang [1750: 230132] casarse 3: 0x 60800004 ABC 0- (
Valor 1,
Valor 2
) 2017-07-2019:48:24.540 beck.Wang [1750:230132] Dirección del elemento de matriz: valor 1: 0x 60800006 df 40-valor 2: 0x 60800006 CB 402017-07-2065438
Valor 1aaa,
Valor 2
Wang [1750: 230132] casarse 2: 0x 6080000023 f00-(
Valor 1aaa,
Valor 2
Wang [1750: 230132] casarse 3: 0x 608000004 ABC 0-(
Valor 1aaa,
Valor 2
) 2017-07-2019: 48: 24.541 beck Wang [1750: 230132] Dirección del elemento de matriz: valor 1: 0x 60800006 df 40 - valor 2: 0x 6080006 CB 402017-07-206
Análisis: antes de modificar el valor original, las direcciones de casarse1, casarse2 y marr3 son diferentes. Obviamente, copiar y mutableCopy son copias profundas, pero a juzgar por los resultados de la impresión después de modificar el valor original, la copia profunda aquí es solo. una copia profunda de una sola capa: La dirección de memoria se abre recientemente, pero el valor en la matriz aún apunta a la matriz original, por lo que el valor en Marr3 y Marr3 se puede modificar. Además, es obvio. de las direcciones de elementos de matriz impresas que se casan1, se casan y La dirección del elemento de matriz de marr3 es exactamente la misma antes y después de la modificación, lo que demuestra aún más este punto
? objeto de colección
Para los objetos mencionados en 2.2., la copia profunda es solo una copia profunda de una sola capa. ¿Hay alguna forma de lograr una copia profunda de cada capa?
Actualmente podemos hacer esto:
? (1) Solución de archivado
-(nulo) copia completa
{
NSMutableArray * casarse 1 = [[NSMutableArray alloc]init];
NSMutableString * mstr 1 =[[NSMutableString alloc]init withstring:@"value 1"];
NSMutableString * mstr 2 =[[NSMutableString alloc]init withstring:@"value 2"] ;
[casarse 1 agregar objeto: mstr 1];
[casarse 1 agregar objeto: mstr 2];
ns data * data =[nskeydarchiver archivedDataWithRootObject: casarse con 1];
NSArray * marray 2 =[nskeydunarchiver unarchiveTopLevelObjectWithData: Error de datos: nulo];
NSLog(@"marry1: p-@\r\n",casarse con 1 ,casarse 1);
NSLog(@"casarse 2: p-@\r\n",marray2,marray 2);
NSLog(@"dirección del elemento de matriz: Valor 1: p-valor2: p\r\n",casarse con 1[0],casarse con 1[1]);
NSLog(@"Dirección del elemento de matriz: valor1: valorp2: p\ r \n", casar 2[0], casar 2[1]);
}
? Resultado de impresión:
2017-07-2020:04:38.726
Valor 1,
Valor 2
Wang [1833: 242158 】María 2: 0x600000049780-(
Valor 1,
Valor 2
) 2017-07-2020:04:38.726 beck.Wang[1833:242158 ] Dirección del elemento de matriz: Valor 1: 0x 6000006300 - Valor 2: 0x 6000000670002017-07-07-2020: 04: 38.726 Wang [1833:
Análisis: Podemos ver que al abrir una nueva dirección de memoria, las direcciones de puntero de los elementos de la matriz son diferentes, logrando una copia profunda completa.
(2)-(tipo de instancia) initwith matriz: (NSArray lt; tipo de objeto gt*) elementos de copia de matriz: (BOOL) bandera
-(void) implementarfullcopy 2<; /p>
{
NSMutableArray * casarse 1 =[[NSMutableArray alloc]init];
NSMutableString * mstr 1 =[[NSMutableString alloc]init withstring:@"valor 1"];
NSMutableString * mstr 2 =[[NSMutableString alloc] init withstring: @"value 2"];
[casarse con 1 agregar objeto: mstr 1]; p>
p>
[casarse 1 agregar objeto: mstr 2];
NSArray * marray 2 =[[NSArray alloc]init con matriz: casarse 1 copiar elementos: SÍ];
NSLog(@"casarse1: p-@\r\n",casarse 1,casarse 1);
NSLog(@"casarse 2: p-@\r\n" ,marray2,marray 2 );
NSLog (@"Dirección del elemento de matriz: valor 1: p-valor2: p\r\n", casar 1[0], casar 1[1]); /p>
NSLog(@"dirección del elemento de matriz: valor1: valor p2: p\r\n", matrimonio 2【0】, matrimonio 2【1]); p>
Resultado de impresión:
王[1868:24616650320-(
Valor 1,
Valor 2
Wang [ 1868:246161] Mary 2: 0x6100002214c0 - (
Valor 1,
Valor 2
Dirección del elemento de matriz: Valor 1: 0x 61000265600 - Valor 2: 0x 610002664002017
? Análisis: igual que el anterior
3. Directrices
No1: Los métodos de copia y copia mutable de objetos variables son copias profundas (para distinguir entre ellos). copias en profundidad completas y copias en profundidad de una sola capa).
? No2: El método de copia de objetos inmutables es la copia superficial y el método de copia mutable es la copia profunda.
? NO3: El objeto devuelto por el método de copia es un objeto inmutable.
? Miles de palabras forman una imagen.