NSArray 딥 카피
딥 카피를 할 수있는 내장 함수가 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];
}
}
}
}
더 깨끗하고 간결한 솔루션을 원합니다.
딥 카피에 관한 Apple 문서 에는 다음과 같이 명시되어 있습니다.
1 단계 딥 사본 만 필요한 경우 :
NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:oldArray copyItems:YES];
위의 코드는 멤버가 이전 배열 멤버의 얕은 복사 본인 새 배열을 만듭니다.
연결된 Apple 문서가 진정한 딥 카피 라고하는 전체 중첩 된 데이터 구조를 깊게 복사해야하는 경우이 방법으로는 충분하지 않습니다. 이에 대한 다른 답변을 참조하십시오.
내가 이것을 쉽게하는 유일한 방법은 배열을 보관하고 즉시 보관 취소하는 것입니다. 약간의 해킹처럼 느껴지지만 실제로 컬렉션 복사 에 대한 Apple 설명서 에서 다음과 같이 명시 적으로 제안됩니다 .
배열 배열이있을 때와 같이 실제 깊은 사본이 필요한 경우 내용이 모두 NSCoding 프로토콜을 준수하는 경우 컬렉션을 보관 한 다음 보관을 취소 할 수 있습니다. 이 기술의 예가 Listing 3에 표시되어있다.
Listing 3 진정한 딥 카피
NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject:oldArray]];
여기서는 데이터를 저장 /로드하는 데 사용되므로 개체가 NSCoding 인터페이스를 지원해야합니다.
스위프트 2 버전 :
let trueDeepCopyArray = NSKeyedUnarchiver.unarchiveObjectWithData(
NSKeyedArchiver.archivedDataWithRootObject(oldArray))
기본적으로 복사하면 얕게 복사됩니다.
그 이유는 전화 copy 은 copyWithZone:NULL기본 영역을 사용한 복사와 동일 입니다. copy호출 딥 카피 발생하지 않습니다. 대부분의 경우 얕은 사본을 제공하지만 어쨌든 수업에 따라 다릅니다. 자세한 내용 은 Apple 개발자 사이트 에서 Collections Programming Topics 를 권장합니다 .
initWithArray : CopyItems : 1 단계 딥 카피 제공
NSArray *deepCopyArray = [[NSArray alloc] initWithArray:someArray copyItems:YES];
NSCoding 깊은 사본을 제공하는 Apple 권장 방법입니다
진정한 딥 카피 (배열 배열)를 위해서는 NSCoding객체를 보관하고 보관 취소해야합니다.
NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]];
딕 토너 리
NSMutableDictionary *newCopyDict = (NSMutableDictionary *)CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFDictionaryRef)objDict, kCFPropertyListMutableContainers);
배열
NSMutableArray *myMutableArray = (NSMutableArray *)CFPropertyListCreateDeepCopy(NULL, arrData, kCFPropertyListMutableContainersAndLeaves);
아니요, 이것을 위해 프레임 워크에 내장 된 것이 없습니다. 코코아 컬렉션은 얕은 복사본을 지원합니다 (copy 또는 arrayWithArray:방법으로) 하지만 깊은 사본 개념에 대해서는 이야기조차하지 않습니다.
컬렉션의 내용이 사용자 지정 개체를 포함하여 시작될 때 "딥 카피"를 정의하기가 어렵 기 때문입니다. "딥 카피" 는 객체 그래프의 모든 객체가every object in the original object graph?
가상적인 것이 있다면 NSDeepCopying protocol, you could set this up and make decisions in all of your objects, but unfortunately there isn't. If you controlled most of the objects in your graph, you could create this protocol yourself and implement it, but you'd need to add a category to the Foundation classes as necessary.
@AndrewGrant's answer suggesting the use of keyed archiving/unarchiving is a nonperformant but correct and clean way of achieving this for arbitrary objects. This book even goes so far so suggest adding a category to all objects that does exactly that to support deep copying.
I have a workaround if trying to achieve deep copy for JSON compatible data.
Simply take NSData of NSArray using NSJSONSerialization and then recreate JSON Object, this will create a complete new and fresh copy of NSArray/NSDictionary with new memory references of them.
But make sure the objects of NSArray/NSDictionary and their children must be JSON serializable.
NSData *aDataOfSource = [NSJSONSerialization dataWithJSONObject:oldCopy options:NSJSONWritingPrettyPrinted error:nil];
NSDictionary *aDictNewCopy = [NSJSONSerialization JSONObjectWithData:aDataOfSource options:NSJSONReadingMutableLeaves error:nil];
참고URL : https://stackoverflow.com/questions/647260/deep-copying-an-nsarray
'IT story' 카테고리의 다른 글
| MySQL 뷰 목록을 얻는 방법? (0) | 2020.07.18 |
|---|---|
| int 숫자의 별도 숫자를 얻는 방법? (0) | 2020.07.18 |
| 크기 제한이있는 캐시 된 스레드 풀을 만들 수 없습니까? (0) | 2020.07.18 |
| Typescript와 함께 Object.values를 사용하는 방법은 무엇입니까? (0) | 2020.07.18 |
| Entity Framework 5에 자식 개체의 자식 개체를 포함시키는 방법 (0) | 2020.07.18 |