문제

차이점은 무엇입니까? 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 변이 가능합니다! copying NSMutableArray 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.

이 복사 내용의 반환 유형을 알아야하며, 새로운 객체를 할당 할 새 개체를 선언하는 동안 반환 값이 불변 또는 변한 값이어야합니다. 그렇지 않으면 컴파일러가 오류를 표시합니다.

복사 된 객체는 새 객체를 사용하여 수정할 수 없으며, 이제 완전히 두 개의 다른 객체입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top