iOS의 얕은 복제 및 깊이 복제

인용하다


대상 복제에 대해 이야기할 때 얕은 복제와 깊은 복제의 구분을 벗어날 수 없는데, 그것들은 무슨 뜻입니까?
  • 얕은 복제: 대상의 바늘만 복제하고 두 대상이 같은 주소의 내용을 가리키며 하나를 조작할 때 다른 값에 영향을 준다.
  • 깊이 복제: 두 대상이 서로 다른 주소의 내용을 가리키며 하나를 조작할 때 다른 값에 영향을 주지 않는다.

  • OC에서 메모리 계수를 사용하는 방식으로 메모리를 관리하기 때문에 얕은 복제는 같은 내용의 계수에 하나를 더하고 깊은 복제는 하지 않는다.
    OC에서 복제 작업에는 코피와mutable Copy 두 가지 방법이 있는데 어떤 것이 얕은 복제이고 어떤 것이 깊은 복제입니까?

    비집합 대상


    먼저 대상을 크게 두 종류로 나눈다. 비집합 대상과 집합 대상이다. 왜 이렇게 나뉘는지 이따가 집합 대상을 이야기할 때 다시 이야기하자.
    비집합 대상은 NSString, NSNumber 등 그 자체가 구체적인 내용의 대상을 가리킨다.NSString 같은 객체에는 NSMutableString이라는 연관성이 있습니다.그래서 비집합 대상에서 가변 대상과 불변 대상으로 나눌 수 있다.
    이들에게 copy와 mutable Copy를 수행하는 의미는 다음과 같습니다.
  • 변할 수 없는 비집합 대상(예를 들어 NSString)에 대해 코피 작업은 얕은 복제이고 바늘만 복제하고mutableCopy 작업은 깊은 복제이다
  • 가변 비집합 대상(예를 들어 NSMutable String)에 대해copy와mutable Copy는 모두 깊이 복제되어 같은 내용을 새로 만들어서 되돌려줍니다. 그러나 주의해야 할 것은copy가 되돌려주는 것은 가변 대상이 아닙니다. 즉, 한 NSMutable String에 대해 copy 작업을 하더라도 다른 NSMutable String에 되돌려주고 이 NSMutable String에 변화 작업을 하면 오류가 발생합니다.

  • 코드는 다음과 같습니다.
    NSString *string = @"origin";
    NSString *stringCopy = [string copy];//  
    NSMutableString *stringMCopy = [string mutableCopy];//  
    
    NSMutableString *string = [NSMutableString stringWithString: @"origin"];
    NSString *stringCopy = [string copy];//  
    NSMutableString *mStringCopy = [string copy];//  
    NSMutableString *stringMCopy = [string mutableCopy];//  
    [mStringCopy appendString:@"mm"]; // crash

    집합 대상


    위에서 비집합 대상이라고 말했는데, 그럼 무엇이 집합 대상입니까?집합 대상은 NSArray, NSDictionary, NSSet 등 다른 대상을 포함하는 대상을 가리킨다.
    왜 이 구분을 해야 되지?얕은 복제, 깊은 복제라는 두 개념은 사실 완전하지 않기 때문에 더욱 정확한 것은 세 가지로 나눌 수 있다. 그것이 바로 얕은 복제, 깊은 복제, 완전한 깊은 복제이다.
    OC에서 하나의 집합 대상에 대해 깊은 복제를 할 때 이 깊은 복제는 단지 단층일 뿐이고 집합 안의 원소 대상은 사실 인용일 뿐이지 모든 층이 깊은 복제가 아니다. 이 경우 애플은 단층 깊은 복제(one-level-deep copy)로 정의한다.집합 안의 모든 층을 깊이 복제해야만 완전 깊이 복제라고 할 수 있다.
    먼저 간단한 얕은 복제와 깊은 복제를 말하지만 사실은 비집합 대상과 차이가 많지 않다.
  • 변할 수 없는 집합 대상(예를 들어 NSArray)에 대해 코피 작업은 얕은 복제이고 바늘만 복제하고mutableCopy 작업은 깊은 복제이다
  • 가변 집합 대상(예를 들어 NSMutable Array)에 대해copy와mutable Copy는 모두 깊이 복제되어 똑같은 내용을 새로 만들어서 되돌려준다. 그러나 두 가지를 주의해야 한다. 첫째,copy가 되돌려주는 것이냐 안 되돌려주는 것이냐. 둘째, 위에서 말한 바와 같이 이 깊이 복제는 단층 깊이 복제일 뿐이고 안에 포함된 요소는 지침이 얕은 복제이다.

  • 코드는 다음과 같습니다.
    NSArray *array = @[@[@"a", @"b"], @[@"c", @"d"];
    NSArray *copyArray = [array copy];//  
    NSMutableArray *mCopyArray = [array mutableCopy];//  
    
    NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
    NSArray *copyArray = [array copy];//  , 
    NSMutableArray *mCopyArray = [array mutableCopy];//  

    그럼 완전 딥 클로닝을 하려면 어떻게 해야 하나요?
    다음과 같은 두 가지 방법이 있습니다.
  • 하나는 다음과 같은 방법으로 한다.
  • NSDictionary shallowCopyDict = [[NSDictionary alloc] initWithDictionary:someDictionary copyItems:YES];

    copyItems를 YES로 설정하면 컬렉션에 있는 각 객체에 대해 딥 클로닝을 시도하지만 컬렉션에 있는 요소 객체에 NSCopying 프로토콜을 따라야 합니다. 그렇지 않으면 오류가 발생합니다.그러나 이것은 사실 원소라는 층에 대한 단층 깊이 복제였고 더 이상 완전히 깊이 복제되지 않았다.
  • 또 다른 방법은 집합을 압축 파일과 해제하는 것이다. (압축 파일과 해제는 전송문:iOS 저장 방식의 압축 파일로 볼 수 있다):
  • NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]];

    맺다


    이상은 OC에서 얕은 복제와 깊은 복제의 각종 응용이다. 얕은 복제인지 깊은 복제인지 스스로 테스트하려면 대상의 인용 계수가 증가했는지 확인할 수 있다.
    NSLog(@"mArray retain count: %d", [mArray retainCount]);// ARC 

    또는 두 객체의 주소가 일치하는지 직접 확인합니다.
    NSLog(@"string :%x", &str);
    NSLog(@"string :%p", str);

    저작권 소유:http://blog.csdn.net/cloudox_

    좋은 웹페이지 즐겨찾기