문제

내장 기능이 있습니까? NSMutableArray?

나는 주위를 둘러 보았다고 일부 사람들은 말한다 [aMutableArray copyWithZone:nil] 딥 카피로 작동합니다. 그러나 나는 시도했고 그것은 얕은 사본 인 것 같습니다.

지금 나는 수동으로 사본을 for 고리:

//deep copy a 9*9 mutable array to a passed-in reference array

-deepMuCopy : (NSMutableArray*) array 
    toNewArray : (NSMutableArray*) arrayNew {

    [arrayNew removeAllObjects];//ensure it's clean

    for (int y = 0; y<9; y++) {
        [arrayNew addObject:[NSMutableArray new]];
        for (int x = 0; x<9; x++) {
            [[arrayNew objectAtIndex:y] addObject:[NSMutableArray new]];

            NSMutableArray *aDomain = [[array objectAtIndex:y] objectAtIndex:x];
            for (int i = 0; i<[aDomain count]; i++) {

                //copy object by object
                NSNumber* n = [NSNumber numberWithInt:[[aDomain objectAtIndex:i] intValue]];
                [[[arrayNew objectAtIndex:y] objectAtIndex:x] addObject:n];
            }
        }
    }
}

그러나 더 깨끗하고 간결한 솔루션을 원합니다.

도움이 되었습니까?

해결책

로서 사과 문서 상태,

하나의 수준 깊이 사본 만 필요하면 명시 적으로 전화를 걸 수 있습니다 ...

NSMutableArray *newArray = [[NSMutableArray alloc] 
                             initWithArray:oldArray copyItems:YES];

위의 코드는 멤버가 이전 배열 멤버의 얕은 사본 인 새로운 배열을 만듭니다.

전체 중첩 된 데이터 구조를 깊이 복사 해야하는 경우 링크 된 Apple 문서가 "진정한 딥 카피" - 그러면이 접근법으로는 충분하지 않을 것입니다 - 여기에서 다른 답변을 참조하십시오.

다른 팁

내가 쉽게 이것을하는 것을 아는 유일한 방법은 배열을 보관 한 다음 즉시 미확인하는 것입니다. 약간의 해킹처럼 느껴지지만 실제로는 명시 적으로 제안됩니다. 컬렉션 복사에 대한 Apple 문서, 여기서 :

배열 배열이있을 때와 같은 진정한 딥 카피가 필요한 경우 컨텐츠가 모두 NSCoding 프로토콜을 준수하면 컬렉션을 보관 한 다음 컬렉션을 해제 할 수 있습니다. 이 기술의 예는 Listing 3에 나와 있습니다.

목록 3 진정한 딥 카피

NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
          [NSKeyedArchiver archivedDataWithRootObject:oldArray]];

캐치는 객체가 NSCoding 인터페이스를 지원해야한다는 것입니다. 이는 데이터를 저장/로드하는 데 사용되기 때문입니다.

스위프트 2 버전 :

let trueDeepCopyArray = NSKeyedUnarchiver.unarchiveObjectWithData(
    NSKeyedArchiver.archivedDataWithRootObject(oldArray))

기본적으로 사본은 얕은 사본을 제공합니다

그것은 전화하기 때문입니다 copy 와 같다 copyWithZone:NULL 기본 영역을 복사하는 것으로 알려져 있습니다. 그만큼 copy 호출은 깊은 사본을 초래하지 않습니다. 대부분의 경우 얕은 사본을 줄 것이지만 어쨌든 그것은 클래스에 따라 다릅니다. 철저한 토론을 위해 나는 추천합니다 컬렉션 프로그래밍 주제 Apple Developer 사이트에서.

initwitharray : Copyitems : 한 레벨의 딥 카피를 제공합니다

NSArray *deepCopyArray = [[NSArray alloc] initWithArray:someArray copyItems:YES];

NSCoding 사과가 깊은 사본을 제공하는 권장 방법입니까?

진정한 딥 카피 (배열)를 위해서는 필요합니다. NSCoding 그리고 아카이브/아키텍트 객체 :

NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]];

Dictonary를 위해

NSMutableDictionary *newCopyDict = (NSMutableDictionary *)CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFDictionaryRef)objDict, kCFPropertyListMutableContainers);

배열 용

NSMutableArray *myMutableArray = (NSMutableArray *)CFPropertyListCreateDeepCopy(NULL, arrData, kCFPropertyListMutableContainersAndLeaves);

아니요,이를 위해 프레임 워크에 내장 된 것이 없습니다. 코코아 컬렉션은 얕은 사본을 지원합니다 ( copy 아니면 그 arrayWithArray: 방법) 그러나 딥 카피 개념에 대해서도 이야기하지 마십시오.

컬렉션의 내용이 자신의 사용자 정의 객체를 포함하여 시작함에 따라 "딥 카피"가 정의하기가 어려워지기 때문입니다. "딥 카피"를 의미합니다 모든 객체 그래프의 객체는 모든 원래 객체 그래프의 객체?

가설이 있다면 NSDeepCopying 프로토콜, 당신은 이것을 설정하고 모든 객체에서 결정을 내릴 수 있지만 불행히도 그렇지 않습니다. 그래프에서 대부분의 객체를 제어 한 경우이 프로토콜을 직접 작성하고 구현할 수 있지만 필요에 따라 기초 클래스에 카테고리를 추가해야합니다.

@Andrewgrant의 답변은 키가있는 아카이빙/미확인의 사용을 제안하는 대답은 임의의 대상에 대해이를 달성하는 비 성능이지만 정확하고 깨끗한 방법입니다. 이 책은 심지어 지금까지갑니다 깊은 복사를 지원하기 위해 정확히 수행하는 모든 객체에 카테고리를 추가합니다.

JSON 호환 데이터에 대한 딥 카피를 달성하려는 경우 해결 방법이 있습니다.

간단히 가져 가십시오 NSDataNSArray 사용 NSJSONSerialization 그런 다음 JSON 개체를 재현하면 완전한 새롭고 신선한 사본을 만듭니다. NSArray/NSDictionary 그들에 대한 새로운 기억 참조.

그러나 nsarray/nsdictionary의 대상과 자녀의 물체가 JSON 직렬화 가능해야합니다.

NSData *aDataOfSource = [NSJSONSerialization dataWithJSONObject:oldCopy options:NSJSONWritingPrettyPrinted error:nil];
NSDictionary *aDictNewCopy = [NSJSONSerialization JSONObjectWithData:aDataOfSource options:NSJSONReadingMutableLeaves error:nil];
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top