원본 코드 를 통 해 iOS 의 깊 은 복사 와 얕 은 복사 분석
iOS 에서 대상 의 깊 은 복사 와 얕 은 복사 에 관 한 글 은 많 지만 대부분 메모리 주 소 를 인쇄 하여 결 과 를 유도 합 니 다.이 글 은 원본 코드 의 측면 에서 깊 은 복사 와 얕 은 복사 를 분석 합 니 다.
딥 카피 와 얕 은 카피 의 개념
복사 방식 은 두 가지 가 있 는데 그것 이 바로 깊 은 복사 와 얕 은 복사 이다.
딥 복사 본 은 실제 복사 본 으로 복사 대상 이 새로운 주 소 를 가리 키 고 있 습 니 다.
위의 그림 에서 알 수 있 듯 이 A 포인터 가 가리 키 는 내용 을 바 꾸 었 고 B 포인터 도 수 정 된 내용 을 가리 키 고 있다.B 지침 을 사용 하 는 곳 이 있 으 면 A 가 가리 키 는 내용 에 도 변 화 를 원 하지 않 을 경우 딥 카피 가 필요 하 다.
얕 은 복사 본 은 당신 의 그림자 와 같 습 니 다.당신 이 죽 으 면 그림자 도 사라 집 니 다.깊 은 복사 본 은 복제 인간 과 같다.네가 죽 었 는데,그것 은 아직 있다.
대상 의 copy 와 mutableCopy 방법
집합 대상 이 든 비 집합 대상 이 든 copy 와 mutableCopy 메 시 지 를 받 을 때 다음 과 같은 준칙 을 따른다.
1.집합 대상 이 아 닌 copy 와 mutableCopy 방법
비 집합 클래스 대상 은 NSString,NSNumber...이런 종 류 를 가리킨다.다음 예 는 NSString 클래스 를 예 로 들 수 있 습 니 다.
우선 immutable 대상 복사 예 를 살 펴 보 겠 습 니 다.
NSString *string = @"test";
NSString *copyString = [string copy];
NSMutableString *mutableCopyString = [string mutableCopy];
NSLog(@"%p
%p
%p
", string, copyString, mutableCopyString);
인쇄 결과:0x101545068
0x101545068
0x60000024e940
인쇄 결 과 를 통 해 알 수 있 듯 이 copyString 은 string 의 주소 값 과 같 고 mutableCopyString 과 string 의 주소 값 이 다 릅 니 다.이것 은 imutable 대상 의 copy 방법 이 얕 은 복사,mutableCopy 방법 이 깊 은 복사 되 었 음 을 설명 합 니 다.
mutable 대상 복사 예 를 살 펴 보 겠 습 니 다.
NSMutableString *string = [[NSMutableString alloc] initWithString:@"test"];
NSString *copyString = [string copy];
NSMutableString *mutableCopyString = [string mutableCopy];
NSLog(@"%p
%p
%p
", string, copyString, mutableCopyString);
인쇄 결과:0x600000240e40
0xa000000747365744
0x6000002411a0
인쇄 결 과 를 통 해 알 수 있 듯 이 copyString 과 string 의 메모리 주소 가 다 르 고 mutableCopyString 과 string 의 메모리 주소 도 다르다.이 는 mutable 대상 의 copy 방법 과 mutable Copy 방법 이 모두 딥 복사 되 었 음 을 나타 낸다.
총괄 적 으로 말 하면:
immutable 대상 의 copy 방법 을 얕 게 복사 하 였 습 니 다.
immutable 대상 의 mutableCopy 방법 을 깊이 복사 하 였 습 니 다.
mutable 대상 의 copy 방법 을 깊이 복사 하 였 습 니 다.
mutable 대상 의 mutable Copy 방법 을 깊이 복사 하 였 습 니 다.
코드 로 표시 하면:
[immutableObject copy];//
[immutableObject mutableCopy];//
[mutableObject copy];//
[mutableObject mutableCopy];//
이상 은 메모리 주 소 를 인쇄 하여 얻 은 결론 입 니 다.다음은 소스 코드 를 통 해 우리 의 결론 을 확인 하 겠 습 니 다.opensource.apple.com 의 git 창고 에 있 는 runtime 소스 코드 에는 NSObject.mm 라 는 파일 이 있 습 니 다.이 파일 에는 copy 와 mutableCopy 방법 이 실 현 됩 니 다.
- (id)copy {
return [(id)self copyWithZone:nil];
}
- (id)mutableCopy {
return [(id)self mutableCopyWithZone:nil];
}
우 리 는 copy 와 mutableCopy 방법 이 copy WithZone:과 mutableCopy WithZone:두 가지 방법 만 간단하게 호출 된 것 을 발견 했다.그리고 나 서 나 는searchcode.com에서 NSString 과 NSMutableString 의 Source Code 를 찾 았 다.NSString.m에서 copy 에 관 한 방법 을 찾 았 습 니 다.
- (id)copyWithZone:(NSZone *)zone {
if (NSStringClass == Nil)
NSStringClass = [NSString class];
return RETAIN(self);
}
- (id)mutableCopyWithZone:(NSZone*)zone {
return [[NSMutableString allocWithZone:zone] initWithString:self];
}
이 소스 코드 를 통 해 알 수 있 듯 이 NSString 대상 에 대해 copy 방법 을 호출 하 는 것 은 copy WithZone:방법 을 호출 하 는 것 입 니 다.한편,copy With Zone:방법 은 새로운 대상 을 만 들 지 않 고 포인터 로 하여 금 원래 의 NSString 대상 을 가지 게 하기 때문에 NSString 의 copy 방법 은 얕 은 복사 입 니 다.mutableCopy 를 호출 하 는 방법 은 mutableCopyWithZone:방법 을 호출 하 는 것 입 니 다.mutableCopyWithZone:의 실현 을 통 해 알 수 있 듯 이 이 방법 은 새로운 가 변 적 인 문자열 대상 을 만 드 는 것 입 니 다.따라서 NSString 의 mutableCopy 방법 은 딥 카피 입 니 다.
NSMutableString.m에서 copy 와 copy WithZone:방법 만 찾 았 을 뿐 mutable Copy WithZone:방법 은 찾 지 못 했 습 니 다.
-(id)copy {
return [[NSString alloc] initWithString:self];
}
-(id)copyWithZone:(NSZone*)zone {
return [[NSString allocWithZone:zone] initWithString:self];
}
NSMutablestring 대상 에 copy 방법 을 호출 하면 이 곳 의 copy With Zone:방법 이 실 현 됩 니 다.새로운 가 변 적 이지 않 은 문자열 을 만 드 는 것 을 볼 수 있 습 니 다.그래서 NSMutablestring 대상 에 대한 copy 방법 은 딥 복사 입 니 다.NSMutablestring 에서 mutableCopyWithZone:방법 이 구현 되 지 않 았 기 때문에 부모 클래스 의 mutableCopyWithZone:방법,즉 NSString 류 의 mutableCopyWithZone:방법 을 호출 합 니 다.NSString 류 의 mutableCopyWithZone:방법 은 새로운 가 변 문자열 을 만 들 수 있 습 니 다.그래서 NSMutablestring 대상 에 게 mutableCopy 를 실행 하 는 방법 은 딥 복사 입 니 다.
2.집합 대상 의 copy 와 mutableCopy
집합 대상 은 NSArray,NSDictionary,NSSet 등 과 같은 대상 을 가리킨다.다음은 NSArray 를 예 로 들 어 immutable 대상 이 copy 와 mutableCopy 를 사용 하 는 예 를 살 펴 보 겠 습 니 다.
NSArray *array = @[@"1", @"2", @"3"];
NSArray *copyArray = [array copy];
NSMutableArray *mutableCopyArray = [array mutableCopy];
NSLog(@"%p
%p
%p", array, copyArray, mutableCopyArray);
인쇄 결과:0x60400025bed0
0x60400025bed0
0x60400025c2f0
인쇄 결 과 를 통 해 알 수 있 듯 이 copy Array 의 주소 와 array 의 주 소 는 같 으 며,array 에 대해 copy 를 하 는 것 은 얕 은 복사 임 을 나타 낸다.그리고
mutableCopyArray 의 주소 와 array 의 주 소 는 다 릅 니 다.array 에 대해 mutableCopy 를 하 는 것 은 깊이 복사 한 것 을 의미 합 니 다.
mutable 대상 이 copy 와 mutableCopy 를 실행 하 는 예 를 살 펴 보 겠 습 니 다.
NSMutableArray *array = [[NSMutableArray alloc] initWithArray:@[@"1", @"2", @"3"]];
NSArray *copyArray = [array copy];
NSMutableArray *mutableCopyArray = [array mutableCopy];
NSLog(@"%p
%p
%p", array, copyArray, mutableCopyArray);
인쇄 결과:0x604000447440
0x604000447050
0x604000447080
인쇄 결 과 를 통 해 알 수 있 듯 이 copy Array 와 mutableCopyArray 의 주 소 는 모두 array 의 주소 와 다 릅 니 다.이 는 가 변 배열 에 대해 copy 와 mutableCopy 작업 을 모두 깊이 복사 한 것 을 의미 합 니 다.
그래서 결론 을 내 렸 다.
집합 클래스 대상 에서 immutable 대상 에 대해 copy 작업 을 하 는 것 은 얕 은 복사 이 고 mutableCopy 작업 을 하 는 것 은 깊 은 복사 입 니 다.mutable 대상 에 대해 copy 작업 을 하 는 것 은 깊 은 복사 이 고 mutable Copy 작업 을 하 는 것 은 깊 은 복사 입 니 다.
코드 로 표시 하면:
[immutableObject copy];//
[immutableObject mutableCopy];//
[mutableObject copy];//
[mutableObject mutableCopy];//
이상 은 메모리 주 소 를 인쇄 하여 얻 은 결론 입 니 다.다음은 소스 코드 를 통 해 우리 의 결론 을 검증 하 겠 습 니 다.NSArray.m에서 나 는 copy WithZone:mutable Copy WithZone:방법 을 찾 았 다.
- (id)copyWithZone:(NSZone *)zone
{
return RETAIN(self);
}
- (id)mutableCopyWithZone:(NSZone*)zone
{
if (NSMutableArrayClass == Nil)
NSMutableArrayClass = [NSMutableArray class];
return [[NSMutableArrayClass alloc] initWithArray:self];
}
copy 방법 을 호출 할 때 실제 적 으로 이곳 의 copy With Zone:방법 을 실 행 했 습 니 다.이 방법 에 서 는 새로운 대상 을 만 들 지 않 고 오래된 대상 만 가지 고 있 기 때문에 가 변 적 이지 않 은 배열 대상 에 대해 copy 작업 을 수행 하 는 것 은 얕 은 복사 입 니 다.mutableCopy 방법 을 호출 할 때 실제 적 으로 이곳 의 mutableCopy With Zone:방법 을 실 행 했 습 니 다.이 방법 에서 원래 의 배열 대상 을 이용 하여 새로운 가 변 배열 대상 을 만 들 었 기 때문에 가 변 적 이지 않 은 배열 대상 에 대해 서 는 mutableCopy 작업 을 깊이 복사 합 니 다.
NSArray.m이 파일 의 825 줄 은 NSMutable Array 의 실현 입 니 다.875 줄 에서 copy With Zone:의 실현 을 찾 았 습 니 다.mutable Copy With Zone:의 실현 을 찾 지 못 했 습 니 다.
- (id)copyWithZone:(NSZone*)zone
{
if (NSArrayClass == Nil)
NSArrayClass = [NSArray class];
return [[NSArrayClass alloc] initWithArray:self copyItems:YES];
}
copy 방법 을 호출 할 때 실제 적 으로 여기 있 는 copy With Zone:방법 을 호출 했 습 니 다.이 방법의 실현 에 있어 서 원래 의 가 변 배열 을 이용 하여 새로운 가 변 배열 을 만 들 었 기 때문에 가 변 배열 에 대해 copy 작업 을 수행 하 는 것 은 깊 은 복사 입 니 다.mutableCopy 를 호출 할 때 NSMutableArray 자체 가 mutableCopyWithZone:방법 을 실현 하지 못 했 기 때문에 부모 클래스,즉 NSArray 류 의 실현 을 호출 합 니 다.위 를 통 해 NSArray 의 실현 을 볼 수 있 습 니 다.원 배열 을 이용 하여 새로운 가 변 배열 을 만 들 었 기 때문에 가 변 배열 에 대해 mutableCopy 작업 을 하 는 것 은 깊 은 복사 입 니 다.
고전 면접 문 제 를 풀다.
면접 문제:왜 NSString 유형의 멤버 변수의 수식 속성 은 strong 이 아 닌 copy 를 사용 합 니까?
우선 NSString 유형의 멤버 변 수 를 copy 로 수식 하 는 것 과 strong 으로 수식 하 는 것 의 차 이 를 알 아야 합 니 다.copy 수식 자 를 사용 하면 구성원 변수 에 값 을 부여 할 때 할당 대상 을 copy 작업 한 다음 구성원 변수 에 값 을 부여 합 니 다.strong 수정자 를 사용 하면 copy 작업 을 수행 하지 않 고 할당 되 는 변 수 를 구성원 변수 에 직접 할당 합 니 다.
NSString 형식의 구성원 변수 string 이 있다 고 가정 하고 값 을 부여 합 니 다.
NSString *testString = @"test";
self.string = testString;
만약 이 구성원 변수 가 copy 로 수식 된다 면 다음 과 같 습 니 다.
self.string = [testString copy];
strong 으로 꾸 몄 다 면 copy 작업 이 없습니다.
self.string = testString;
copy 와 strong 의 차 이 를 알 게 된 후,우 리 는 왜 copy 수식 자 를 사용 해 야 하 는 지 다시 분석 합 니 다.코드 먼저 보기:
NSMutableString *mutableString = [[NSMutableString alloc] initWithString:@"test"];
self.string = mutableString;
NSLog(@"%@", self.string);
[mutableString appendString:@"addstring"];
NSLog(@"%@", self.string);
이 멤버 변수 string 이 strong 으로 수식 되 어 있다 면 인쇄 결 과 는 다음 과 같 습 니 다.2018-09-04 10:50:16.909998+0800 copytest[2856:78171] test
2018-09-04 10:50:16.910128+0800 copytest[2856:78171] testaddstring
mutablestring 의 값 이 바 뀌 면 string 의 값 도 달라 집 니 다.self.string=mutablestring 때 문 입 니 다.이 코드 는 실제로 포인터 복사 가 실행 되 었 다.string 의 값 은 mutablestring 의 값 에 따라 달라 집 니 다.이것 은 분명히 우리 가 원 하 는 결과 가 아 닙 니 다.
만약 구성원 변수 string 이 copy 로 수식 된다 면 인쇄 결 과 는 다음 과 같 습 니 다.
2018-09-04 10:58:07.705373+0800 copytest[3024:84066] test
2018-09-04 10:58:07.705496+0800 copytest[3024:84066] test
이것 은 copy 수식 자 를 사용 한 후 self.string=mutablestring;self.string=[mutablestring copy];즉,한 번 깊이 복사 되 었 기 때문에 mutablestring 의 값 이 다시 변 하면 string 의 값 에 영향 을 주지 않 습 니 다.
면접 문제 에 대답 하 다.
NSString 형식의 구성원 변 수 는 strong 수식 이 아 닌 copy 수식 을 사용 합 니 다.가끔 이 구성원 에 게 주어진 변 수 는 NSMutableString 형식 이기 때 문 입 니 다.이때 수정자 가 strong 이면 구성원 변수의 값 은 할당 대상 의 값 에 따라 달라 집 니 다.copy 로 수식 하면 NSMutablestring 형식의 값 을 한 번 깊이 복사 하면 구성원 변수의 값 은 할당 대상 의 값 에 따라 바 뀌 지 않 습 니 다.
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JAVA- 소스 코드 분할(Package 사용)▪️test45.java 소스 코드 ▪️test47.java 소스 코드 ▪️실행 결과 더하면 12, 당기면 8 ▪️예① 클래스 이름에 대한 완전한 입력 생략 import 문 사용 ▪️예① test45.java 소스 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.