OC 언어-08-심층 복사 및 얕은 복사 상해(예)

5722 단어

개술

  • 복제: 소스 객체와 동일한 컨텐츠를 복제
  • 복제를 수행하려면 다음 두 가지 프로토콜을 준수해야 합니다.
  • NSCopying
  • NSMutableCopying

  • 복제 반환 객체 종류
  • 가변,mutableCopy 메시지가 되돌아오는 대상
  • 불변,copy 메시지가 되돌아오는 대상
  • 복제본 종류
  • 얕은 복사, 원본 대상을 가리키는 바늘만 복사, 대상을 만들지 않음, 메모리를 분배하지 않음
  • 딥 카피, 소스 객체 복제, 새 객체 생성, 메모리 할당
  • 주의
  • 시스템은 용기류의 대상과 비용기류의 대상에 대한 메모리 처리가 다르다. 즉, 다른 대상에 의해 강제로 인용되지 않은 대상이 용기에서 제거되면 그 대상은 소각

  • Copy 및 Retain

  • copy
  • 은 새로운 개체를 만드는 것입니다. 컨텐츠 복제본
  • copy는 두 대상의 내용이 같고 새로운 대상의 인용계수는 1
  • 이다.
  • 옛 대상의 인용계수와 상관없이 대상에 변화가 없음
  • copy는 상하문에 대한 대상의 감소
  • retain
  • 포인터, 포인터 복사본
  • 생성
  • 대상의 주소가 같고 내용도 같다
  • 대상의 인용 계수 +1

  • 다른 객체의 복제 동작

  • 비용기 대상 NSString)
  • 불변 객체의 경우
  • 규칙
  • copy, 얕은 복사(포인터 복제)
  • mutableCopy, 깊이 복사(대상 복제), 대상 가변 반환(새로운 가변 대상 생성)
  • - (void)imutableInstanceCopy
    {
        NSString *string = @"Welcome to Xcode";
    
        //copy,   
        NSString *stringCopy = [string copy];
        //mutableCopy,       
        NSMutableString *stringMutableCopy = [string mutableCopy];
        [stringMutableCopy appendString:@"!"];
    
        //string stringCopy       
        NSLog(@"string: %p", string);
        NSLog(@"strongCopy: %p", stringCopy);
    
        //string stringMutableCopy       ,       
        NSLog(@"stringMCopy:%p", stringMutableCopy);
    }
  • 소프트 객체의 경우
  • 규칙
  • copy, 딥 카피(대상 복제), 반환 대상 불변
  • mutableCopy, 딥 카피(대상 복제)
  • - (void)mutableInstanceCopy
    {
        NSMutableString *mutableString = [NSMutableString stringWithString: @"Welcome to Xcode"];
    
        //   ,       
        NSString *stringCopy = [mutableString copy];
        NSMutableString *mutableStringCopy = [mutableString copy];
        //   ,     ,    “Attempt to mutate immutable object with appendString:”
        [mutableStringCopy appendString:@"~~~"];
    
        //   ,      
        NSMutableString *stringMutableCopy = [mutableString mutableCopy];
        [stringMutableCopy appendString:@"!"];
    
        //   mutableString        
        NSLog(@"mutableString: %p", mutableString);
        NSLog(@"string: %p", stringCopy);
        NSLog(@"mutableStringCopy: %p", mutableStringCopy);
        NSLog(@"stringMutbleCopy:%p", stringMutableCopy);
    }

  • 용기 대상NSArray
  • 비용기 대상의 복사 원칙에 따라
  • 주의
  • 용기 내의 원소는 바늘 값(얕은 복사)
  • 이다.
  • - (void)containerInstanceShallowCopy
    {
        NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"Welcome"],@"to",@"Xcode",nil];
    
        //   
        NSArray *arrayCopy = [array copy];
        //   
        NSMutableArray *arrayMutableCopy = [array mutableCopy];
    
        NSLog(@"array: %p", array);
        NSLog(@"arrayCopy: %p", arrayCopy);
        NSLog(@"arrayMutableCopy: %p", arrayMutableCopy);
    
        //          ,           
        NSMutableString *testString = [array objectAtIndex:0];
        [testString appendString:@" you"];
    
        //           
        NSLog(@"array[0]: %@", array[0]);
        NSLog(@"arrayCopy[0]: %@", arrayCopy[0]);
        NSLog(@"arrayMutableCopy[0]: %@", arrayMutableCopy[0]);
    }
  • 진정한 의미의 딥 클로닝 실현
    - (void)containerInstanceDeepCopy
    {
        NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"Welcome"],@"to",@"Xcode",nil];
    
        //          
        NSArray *deepCopyArray = [[NSArray alloc] initWithArray:array];
        //        ,          
        NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array]];
    
        NSLog(@"array: %p", array);
        NSLog(@"deepCopyArray: %p", deepCopyArray);
        NSLog(@"trueDeepCopyArray: %p", trueDeepCopyArray);
    
        //  array      
        [[array objectAtIndex:0] appendString:@" you"];
    
        //   deepCopyArray        
        NSLog(@"array[0]: %@", array[0]);
        NSLog(@"arrayCopy[0]: %@", deepCopyArray[0]);
        //   trueDeepCopyArray        ,          
        NSLog(@"arrayMutableCopy[0]: %@", trueDeepCopyArray[0]);
    }
  • 사용자 정의 객체
  • 객체의 복제본을 정의하려면 NSCoping과 NSMutable Coping 프로토콜을 준수하고 다음과 같은 방법을 수행해야 합니다.
  • - (id) copyWithZone: (NSZone*) zone, 가변 복사
  • - (id) mutableCopyWithZone: (NSZone*) zone, 변경 불가 복사
  • 예제(사용자 정의 Person 복제본)
  • 협의 준수, 구성원 속성 설정
    @interface Person : NSObject <NSCopying, NSMutableCopying>
    /**  */
    @property (nonatomic, copy) NSMutableString *name;
    /**  */
    @property (nonatomic, copy) NSString *address;
    /**  */
    @property (nonatomic, assign) NSInteger age;
    @end
  • 다시 쓰기 초기화 방법
    - (instancetype)init
    {
        if (self = [super init])
        {
            self.name = [[NSMutableString alloc] initWithString:@"XiaoYaowang"];
            self.address = @"    ";
            self.age = 3;
        }
        return self;
    }
  • 실현-(id)copyWithZone: (NSZone*)zone
    - (id)copyWithZone:(NSZone *)zone
    {
        Person *p = [[[self class] allocWithZone:zone] init];
        p.name = [self.name copy];
        p.address = [self.address copy];
        p.age =  self.age;
    
        return p;
    }
  • 실현-(id)mutableCopyWithZone: (NSZone*)zone
    - (id)mutableCopyWithZone:(NSZone *)zone
    {
        Person *p = [[[self class] allocWithZone:zone] init];
        //  ,   mutableCopy  
        p.name = [self.name mutableCopy];
        p.address = [self.address copy];
        p.age =  self.age;
    
        return p;
    }

  • 좋은 웹페이지 즐겨찾기