NSARRAY 및 NSMUTABLEARRAY에 사본 및 MutableCopy가 어떻게 적용됩니까?
-
18-09-2019 - |
문제
차이점은 무엇입니까? copy
그리고 mutableCopy
어느 쪽에도 사용될 때 NSArray
또는 NSMutableArray
?
이것은 나의 이해입니다. 맞습니까?
// ** NSArray **
NSArray *myArray_imu = [NSArray arrayWithObjects:@"abc", @"def", nil];
// No copy, increments retain count, result is immutable
NSArray *myArray_imuCopy = [myArray_imu copy];
// Copys object, result is mutable
NSArray *myArray_imuMuta = [myArray_imu mutableCopy];
// Both must be released later
// ** NSMutableArray **
NSMutableArray *myArray_mut = [NSMutableArray arrayWithObjects:@"A", @"B", nil];
// Copys object, result is immutable
NSMutableArray *myArray_mutCopy = [myArray_mut copy];
// Copys object, result is mutable
NSMutableArray *myArray_mutMuta = [myArray_mut mutableCopy];
// Both must be released later
해결책
copy
그리고 mutableCopy
다른 프로토콜로 정의됩니다 (NSCopying
그리고 NSMutableCopying
, 각각) 및 NSArray
두 가지를 준수합니다. mutableCopy
정의됩니다 NSArray
(뿐만 아니라 NSMutableArray
) 그리고 원래 불변의 배열의 변이 가능한 사본을 만들 수 있습니다.
// create an immutable array
NSArray *arr = [NSArray arrayWithObjects: @"one", @"two", @"three", nil ];
// create a mutable copy, and mutate it
NSMutableArray *mut = [arr mutableCopy];
[mut removeObject: @"one"];
요약:
- 결과에 의존 할 수 있습니다
mutableCopy
원래 유형에 관계없이 변이 가능합니다. 배열의 경우 결과는NSMutableArray
. - 너 할 수 없습니다 결과에 의존합니다
copy
변이 가능합니다!copy
ingNSMutableArray
5월 반환NSMutableArray
, 그것은 원래 클래스이기 때문에copy
임의의 모든 것NSArray
인스턴스는 그렇지 않습니다.
편집하다: Mark Bessey의 답변에 비추어 원본 코드를 다시 읽으십시오. 배열 사본을 만들 때는 물론 사본으로 수행하는 작업에 관계없이 원본을 수정할 수 있습니다. copy
vs mutableCopy
에 영향을 미칩니다 새로운 배열 변이 가능합니다.
편집 2 : 내 (거짓) 가정을 수정했습니다 NSMutableArray -copy
반환 할 것입니다 NSMutableArray
.
다른 팁
나는 당신이 사본과 mutablecopy의 작동 방식을 잘못 해석해야한다고 생각합니다. 첫 번째 예에서 MyArray_copy는 MyArray의 불변 사본입니다. 사본을 만들면 원래 MyArray의 내용을 조작 할 수 있으며 MyArray_copy의 내용에 영향을 미치지 않습니다.
두 번째 예에서는 MyArray의 변이 가능한 사본을 만들므로 다른 사람에게 영향을 미치지 않고 배열의 사본을 수정할 수 있습니다.
MyArray_copy에서 객체를 삽입/제거하려는 첫 번째 예제를 변경하면 예상대로 실패합니다.
아마도 일반적인 사용 사례에 대해 생각하면 도움이 될 것입니다. 종종 당신이 NSArray *
매개 변수, 기본적으로 나중에 사용하기 위해 저장합니다. 이런 식으로 할 수 있습니다.
- (void) doStuffLaterWith: (NSArray *) objects {
myObjects=[objects retain];
}
... 그러나 당신은 논증으로서 nsmutablearray로 메소드를 호출 할 수 있다는 문제가 있습니다. 배열을 생성 한 코드는 Dostufflaterwith : 메소드가 호출 될 때와 나중에 값을 사용해야 할 때 사이에이를 조작 할 수 있습니다. 멀티 스레드 앱에서 배열의 내용도 변경 될 수도 있습니다. 당신이 반복하는 동안, 흥미로운 버그를 일으킬 수 있습니다.
대신 이것을하는 경우 :
- (void) doStuffLaterWith: (NSArray *) objects {
myObjects=[objects copy];
}
.. 그런 다음 사본은 메소드가 호출 될 때 배열의 내용의 스냅 샷을 만듭니다.
"복사"메소드는 nscopying protocols copywithzone을 구현하여 생성 된 객체를 반환합니다.
NSString을 보내는 경우 사본 메시지를 보내는 경우 :
NSString* myString;
NSString* newString = [myString copy];
반환 값은 NSString입니다 (변하지 않음)
MutableCopy 메소드는 NSMutableCopying 프로토콜의 MutableCopywithZone을 구현하여 생성 된 객체를 반환합니다.
보내기 :
NSString* myString;
NSMutableString* newString = [myString mutableCopy];
반환 값 할 것이다 돌연변이 가능합니다.
모든 경우에, 객체는 프로토콜을 구현해야하며, 새 복사 객체를 생성하고이를 반환한다는 것을 나타냅니다.
Nsarray의 경우 얕고 깊은 복사에 관한 추가 수준의 복잡성이 있습니다.
NSARRAY의 얕은 사본은 원래 배열의 객체에 대한 참조 만 복사하여 새 배열에 배치합니다.
결과는 다음과 같습니다.
NSArray* myArray;
NSMutableArray* anotherArray = [myArray mutableCopy];
[[anotherArray objectAtIndex:0] doSomething];
원래 배열에서 인덱스 0의 객체에도 영향을 미칩니다.
딥 카피는 실제로 배열에 포함 된 개별 객체를 복사합니다. 이는 각 개별 객체를 "CopywithZone :"메시지를 보내는 것입니다.
NSArray* myArray;
NSMutableArray* anotherArray = [[NSMutableArray alloc] initWithArray:myArray
copyItems:YES];
변한 객체 복사에 대한 내 잘못된 가정을 제거하기 위해 편집
NSMutableArray* anotherArray = [[NSMutableArray alloc] initWithArray:oldArray
copyItems:YES];
만들 것입니다 anotherArray
그것은 사본입니다 oldArray
깊이 2 레벨로. 대상 인 경우 oldArray
배열입니다. 일반적으로 대부분의 응용 프로그램에서 발생합니다.
글쎄, 우리가 필요하다면 진정한 딥 카피 우리는 사용할 수 있습니다.
NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
[NSKeyedArchiver archivedDataWithRootObject: oldArray]];
이를 통해 모든 레벨이 실제로 복사되어 각 레벨에서 원래 물체의 돌연변이를 유지합니다.
Robert Clarence D 'Almeida, 인도 방갈로르.
당신은 당신이 만든 새 사본이 아니라 원래 배열에서 addobject를 호출하고 원래 배열에서 제거합니다. 호출 Copy vs MutableCopy는 원래 객체가 아니라 객체의 새로운 사본의 돌연변이에만 영향을 미칩니다.
간단히 말하면
- 사본은 어레이의 불변 (수정할 수 없음) 사본을 반환합니다.
- MutableCopy는 배열의 Mutable (수정 될 수 있음) 사본을 반환합니다.
복사 (두 경우 모두)는 원래 배열에 대한 객체 참조 (예 : 원본) 객체가 사본에 참조되어있는 새 배열을 "인구"를 가져옵니다.
MutableCopy에 새로운 물체를 추가하면 MutableCopy에 고유합니다. MutableCopy에서 물체를 제거하면 원래 배열에서 제거됩니다.
두 경우 모두 사본을 만들 때 원래 배열 시점의 스냅 샷으로 생각하십시오.
추정하다
NSArray *A = xxx; // A with three NSDictionary objects
NSMutableArray *B = [A mutableCopy];
B의 내용은 nsdictionary 객체입니다.
-(id)copy always returns a immutable one & -(id)mutableCopy always returns a mutable object,that's it.
이 복사 내용의 반환 유형을 알아야하며, 새로운 객체를 할당 할 새 개체를 선언하는 동안 반환 값이 불변 또는 변한 값이어야합니다. 그렇지 않으면 컴파일러가 오류를 표시합니다.
복사 된 객체는 새 객체를 사용하여 수정할 수 없으며, 이제 완전히 두 개의 다른 객체입니다.