심층 복사와 얕은 복사 사열
하나.기본 유형의 복제본
일반적으로 표준 복제는 간단한 값 부여 작업의 호출을 가리킨다. 즉, =조작부호를 사용하여 하나의 변수를 다른 변수에 부여하는 것이다. 예를 들어 다음과 같다.
int a = 5;
int b;
b = a;
그러면 b는 a의 복사본을 얻었다. b와 a의 메모리 주소는 다르고 그들은 각각 다른 메모리 구역을 차지한다.그러나 만약 당신이 이런 방식으로CoreFoundation 대상을 복제하려고 한다면 복제는 대상의 인용일 뿐이고 대상 자체는 실제 복제되지 않는다.
컨테이너 클래스 대상이든 비컨테이너 클래스 대상이든copy는 변하지 않는 대상을 되돌려주고mutablecopy는 변하지 않는 대상을 되돌려줍니다.
둘.시스템의 비컨테이너 클래스 객체
다음은 비컨테이너 클래스 객체의 복제본
NSString
과 NSMutableString
에 대해 설명합니다. NSString *str = [NSString stringWithFormat:@"123"];
NSString *c= [str copy];// ,str:123 ,cpstr:123
NSLog(@"STR:%p recount = %ld",str,[str retainCount]);
NSLog(@"CPstr:%p recount = %ld",cpstr,[cpstr retainCount]);
2015-08-06 15:37:42.001 TableViewDemo[57923:1652639] STR:0x7fe88272d0f0 recount = 2
2015-08-06 15:37:44.760 TableViewDemo[57923:1652639] CPstr:0x7fe88272d0f0 recount = 2
str와cpstr는 같은 대상을 가리키며,copy 후 대상의 인용 계수는 2로 증가합니다
NSString *str = [NSString stringWithFormat:@"123"];
NSMutableString *cpstr = [str mutableCopy];// ,str:1 ,cpstr:15
NSLog(@"STR:%p recount = %ld",str,[str retainCount]);
NSLog(@"CPstr:%p recount = %ld",cpstr,[cpstr retainCount]);
2015-08-06 15:44:07.437 TableViewDemo[58020:1656801] STR:0x7f8610723090 recount = 1
2015-08-06 15:44:07.437 TableViewDemo[58020:1656801] CPstr:0x7f8610721010 recount = 1
str와cpstr는 서로 다른 대상을 가리키며,mutableCopy는str의 인용 계수에 영향을 주지 않습니다.
NSMutableString *str = [NSMutableString stringWithFormat:@"123"];
NSString *cpstr = [str copy];// ,str:123 ,cpstr:123
NSLog(@"STR:%p recount = %ld",str,[str retainCount]);
NSLog(@"CPstr:%p recount = %ld",cpstr,[cpstr retainCount]);
2015-08-06 15:49:27.503 TableViewDemo[58085:1661052] STR:0x7fdc62739250 recount = 1
2015-08-06 15:49:27.504 TableViewDemo[58085:1661052] CPstr:0x7fdc62737f40 recount = 1
str와cpstr는 서로 다른 대상을 가리키며,copy는str 인용 계수에 영향을 주지 않습니다.또한copy가 얻은 대상은 변할 수 없기 때문에cpstr를 변경할 수 없습니다.
NSMutableString *str = [NSMutableString stringWithFormat:@"123"];
NSMutableString *cpstr = [str mutableCopy];// ,str:123 ,cpstr:123
NSLog(@"STR:%p recount = %ld",str,[str retainCount]);
NSLog(@"CPstr:%p recount = %ld",cpstr,[cpstr retainCount]);
2015-08-06 15:53:21.852 TableViewDemo[58152:1664413] STR:0x7fe69b6515d0 recount = 1
2015-08-06 15:53:21.853 TableViewDemo[58152:1664413] CPstr:0x7fe69b653330 recount = 1
str와cpstr는 서로 다른 대상을 가리키며,mutableCopy는str 인용 계수에 영향을 주지 않습니다.
요약:
시스템의 컨테이너 클래스 객체
우선, 상기 결론(즉 비용기류 대상의 복사 규칙)은 시스템 용기류 대상에 여전히 적용되지만 변화가 있다.
//copy ,mutablecopy
NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSArray *arrayCopy = [array copy];
//arrayCopy1 array NSArray ( ), array
NSLog(@"arrar:%p recount: %ld",array ,[array retainCount]);
NSLog(@"arraycopy:%p recount: %ld",arrayCopy,[arrayCopy retainCount]);
NSLog(@"object of array[0]:%p ,retaincount:%ld",array[0],[array[0] retainCount]);
NSLog(@"object of arrayCopy[0]:%p ,retaincount:%ld",arrayCopy[0],[arrayCopy[0] retainCount]);
2015-08-06 16:30:56.088 TableViewDemo[58790:1689296] arrar:0x7fd7fbf668a0 recount: 2
2015-08-06 16:30:56.088 TableViewDemo[58790:1689296] arraycopy:0x7fd7fbf668a0 recount: 2
2015-08-06 16:30:56.088 TableViewDemo[58790:1689296] object of array[0]:0x7fd7fbf64a80 ,retaincount:2
2015-08-06 16:30:56.089 TableViewDemo[58790:1689296] object of arrayCopy[0]:0x7fd7fbf64a80 ,retaincount:2
용기 자체가 얕은 복사일 뿐만 아니라 용기 안의 원소도 얕은 복사이다.
NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSMutableArray *mArrayCopy = [array mutableCopy];
//mArrayCopy array , array , array1 。mArrayCopy
NSLog(@"arrar:%p recount: %ld",array ,[array retainCount]);
NSLog(@"mArraycopy:%p recount: %ld",mArrayCopy,[mArrayCopy retainCount]);
NSLog(@"object of array[0]:%p ,retaincount:%ld",array[0],[array[0] retainCount]);
NSLog(@"object of mArrayCopy[0]:%p ,retaincount:%ld",mArrayCopy[0],[mArrayCopy[0] retainCount]);
2015-08-06 16:38:13.488 TableViewDemo[58951:1696194] arrar:0x7fd902c1cb50 recount: 1
2015-08-06 16:38:13.497 TableViewDemo[58951:1696194] mArraycopy:0x7fd902c66e10 recount: 1
2015-08-06 16:38:13.497 TableViewDemo[58951:1696194] object of array[0]:0x7fd902c7e400 ,retaincount:3
2015-08-06 16:38:13.497 TableViewDemo[58951:1696194] object of mArrayCopy[0]:0x7fd902c7e400 ,retaincount:3
용기 자체는 깊은 복사이지만 용기 안의 원소는 얕은 복사이다.
NSMutableArray *mArray = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSArray *arrayCppy = [mArray copy];
NSLog(@"mArray:%p recount: %ld",mArray ,[mArray retainCount]);
NSLog(@"array:%p recount: %ld",arrayCppy,[arrayCppy retainCount]);
NSLog(@"object of mArray[0]:%p ,retaincount:%ld",mArray[0],[mArray[0] retainCount]);
NSLog(@"object of arrayCopy[0]:%p ,retaincount:%ld",arrayCppy[0],[arrayCppy[0] retainCount]);
2015-08-06 16:48:23.686 TableViewDemo[59111:1703503] mArray:0x7fdef85076c0 recount: 1
2015-08-06 16:48:23.687 TableViewDemo[59111:1703503] array:0x7fdef8514a10 recount: 1
2015-08-06 16:48:23.687 TableViewDemo[59111:1703503] object of mArray[0]:0x7fdef850f300 ,retaincount:3
2015-08-06 16:48:23.687 TableViewDemo[59111:1703503] object of arrayCopy[0]:0x7fdef850f300 ,retaincount:3
용기 자체는 깊은 복사이지만 용기 안의 원소는 확실히 얕은 복사이다.
NSMutableArray *mArray = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSMutableArray *mMArrayCopy = [mArray mutableCopy];
NSLog(@"mArray:%p recount: %ld",mArray ,[mArray retainCount]);
NSLog(@"mMArrayCopy:%p recount: %ld",mMArrayCopy,[mMArrayCopy retainCount]);
NSLog(@"object of mArray[0]:%p ,retaincount:%ld",mArray[0],[mArray[0] retainCount]);
NSLog(@"object of mMArrayCopy[0]:%p ,retaincount:%ld",mMArrayCopy[0],[mMArrayCopy[0] retainCount]);
2015-08-06 16:50:28.608 TableViewDemo[59165:1705342] mArray:0x7f8aba59b440 recount: 1
2015-08-06 16:50:28.608 TableViewDemo[59165:1705342] mMArrayCopy:0x7f8aba59edf0 recount: 1
2015-08-06 16:50:28.609 TableViewDemo[59165:1705342] object of mArray[0]:0x7f8aba59aff0 ,retaincount:3
2015-08-06 16:50:28.609 TableViewDemo[59165:1705342] object of mMArrayCopy[0]:0x7f8aba59aff0 ,retaincount:3
용기 자체는 깊은 복사이지만 용기 안의 원소는 얕은 복사이다.
요약:
그렇다면 용기 안의 원소를 어떻게 복사합니까?
요소의 깊이 복사
NSArray *deepCopyArray=[[NSArray alloc] initWithArray:someArray copyItems:YES];
예:
NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSArray *deepCopyArray=[[NSArray alloc] initWithArray:array copyItems:YES];
NSLog(@"object of array[0]:%p ,retaincount:%ld",array[1],[array[1] retainCount]);
NSLog(@"object of deepCopyArray[0]:%p ,retaincount:%ld",deepCopyArray[1],[deepCopyArray[1] retainCount]);
NSLog(@"object of array[1]:%p ,retaincount:%ld",array[1],[array[1] retainCount]);
NSLog(@"object of deepCopyArray[1]:%p ,retaincount:%ld",deepCopyArray[1],[deepCopyArray[1] retainCount]);
2017-08-18 15:46:25.560 CopyLearn[30825:19466602] array:0x61000004e490 recount: 1
2017-08-18 15:46:25.560 CopyLearn[30825:19466602] deepCopyArray:0x61000004df80 recount: 1
2017-08-18 15:46:25.560 CopyLearn[30825:19466602] object of array[0]:0x61000006f640 ,retaincount:2
2017-08-18 15:46:25.562 CopyLearn[30825:19466602] object of deepCopyArray[0]:0xa000000000000611 ,retaincount:-1
2017-08-18 15:46:25.562 CopyLearn[30825:19466602] object of array[1]:0x10dd37080 ,retaincount:-1
2017-08-18 15:46:25.562 CopyLearn[30825:19466602] object of deepCopyArray[1]:0x10dd37080 ,retaincount:-1
가변 대상에 대한copy 메시지는 깊은 복사가 가능하지만 @ "b"와 같은 상수 문자열은 본질적으로 얕은 복사입니다.
더 나아가 array를 다음과 같이 수정합니다.
NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@[@"b"],@"c",nil];
이 때 log는 다음과 같이 표시됩니다.
2017-08-18 15:47:52.331 CopyLearn[31018:19471465] array:0x600000245010 recount: 1
2017-08-18 15:47:52.331 CopyLearn[31018:19471465] deepCopyArray:0x600000244d10 recount: 1
2017-08-18 15:47:52.331 CopyLearn[31018:19471465] object of array[0]:0x600000079440 ,retaincount:2
2017-08-18 15:47:52.331 CopyLearn[31018:19471465] object of deepCopyArray[0]:0xa000000000000611 ,retaincount:-1
2017-08-18 15:47:52.331 CopyLearn[31018:19471465] object of array[1]:0x600000004770 ,retaincount:3
2017-08-18 15:47:52.332 CopyLearn[31018:19471465] object of deepCopyArray[1]:0x600000004770 ,retaincount:3
이때, @[@"b"]는 하나의 그룹입니다. 변경할 수 없는 그룹입니다. 이때는 여전히 얕은 복사입니다!
그래서 이런 깊은 복사는 변할 수 없는 대상이 깊은 복사를 실현하지 못했다.
NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject:oldArray]];
인스턴스:
NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject:array]];
NSLog(@"array:%p recount: %ld",array ,[array retainCount]);
NSLog(@"trueDeepCopyArray:%p recount: %ld",trueDeepCopyArray,[trueDeepCopyArray retainCount]);
NSLog(@"object of array[0]:%p ,retaincount:%ld",array[0],[array[0] retainCount]);
NSLog(@"object of trueDeepCopyArray[0]:%p ,retaincount:%ld",trueDeepCopyArray[0],[trueDeepCopyArray[0] retainCount]);
NSLog(@"object of array[1]:%p ,retaincount:%ld",array[1],[array[1] retainCount]);
NSLog(@"object of trueDeepCopyArray[1]:%p ,retaincount:%ld",trueDeepCopyArray[1],[trueDeepCopyArray[1] retainCount]);
2017-08-18 15:52:21.947 CopyLearn[31140:19482635] array:0x600000242670 recount: 1
2017-08-18 15:52:21.947 CopyLearn[31140:19482635] trueDeepCopyArray:0x600000242f10 recount: 1
2017-08-18 15:52:21.947 CopyLearn[31140:19482635] object of array[0]:0x60000006e180 ,retaincount:2
2017-08-18 15:52:21.948 CopyLearn[31140:19482635] object of trueDeepCopyArray[0]:0x60000006e240 ,retaincount:1
2017-08-18 15:52:21.948 CopyLearn[31140:19482635] object of array[1]:0x10d815080 ,retaincount:-1
2017-08-18 15:52:21.948 CopyLearn[31140:19482635] object of trueDeepCopyArray[1]:0xa000000000000621 ,retaincount:-1
이때 수조 내의 모든 원소는 진정한 의미의 깊은 복사를 실현했고 상수를 포함했다.
그렇다면 불가변의 대상도 마찬가지인지에 대한 답은 긍정적이다.
상수의retainCount가 왜 -1인지 궁금한 게 있을지도 몰라요.길을 가리키다
참고 자료
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.