iOS 사용자 지정 객체의 깊이 있는 복제본

3722 단어
iOS 시스템 객체 복제의 경우 다음 규칙을 참조할 수 있습니다.
  • 가변 대상copymutableCopy 방법은 모두 깊이 복사(완전 깊이 복사와 단층 깊이 복사를 구별한다).
  • 불가변 대상의 copy 방법은 얕은 복사이고, mutableCopy 방법은 깊은 복사이다.
  • copy 방법으로 되돌아오는 대상은 모두 변할 수 없는 대상이다.

  • 사용자 지정 객체의 복제본
    시스템의 대상은 가변과 불가변의 구분이 있기 때문에 얕은 복사와 깊은 복사는 좀 복잡하다.사용자 정의 대상은 변할 수 없는 개념이 없기 때문에 심도 있는 복사만 논의한다.
    사용자 정의 대상이 복사를 실현하려면 NSCopying 또는 NSMutableCopying 협의를 체결하고 copyWithZone: 또는 mutableCopyWithZone:를 실현해야 한다.그것들의 실현 방법은 유사하다.
    우선, 사용자 정의 클래스는 copyWithZone: 또는 협의를 체결해야 한다.먼저 사용자 정의 클래스 Person을 만들고 프로토콜을 체결합니다.
    @interface Person : NSObject
    @property (nonatomic, strong) NSString *name;// strong
    @property (nonatomic, assign) NSInteger age;
    @end
    

    그리고 대응하는 방법을 실현하고 실현 중copyWithZone: 방법으로 새로운 대상을 만들고 속성에 값을 부여합니다.속성은 값을 부여할 때도 깊이 있게 복사해야 한다. 그렇지 않으면 속성이 얕게 복사되고 대상의 깊이 복사도 완전하지 않다.이것들을 완성한 후에 사용할 때 이 대상의 allocWithZone: 방법을 직접 호출할 수 있다(코드는 다음과 같다:)
    @implementation Person
    - (id)copyWithZone:(NSZone *)zone {
        Person *p = [[Person allocWithZone:zone] init];
        // 
        p.name = [self.name mutableCopy];
        p.age = self.age;
        return p;
    }
    @end
    
    @implementation ViewController
    Person *p = [[Person alloc] init];
    p.name = [NSString stringWithFormat:@"%@", @" "];
    Person *copyP = [p copy];
    
    NSLog(@"p = %p, copyP = %p", p, copyP);
    NSLog(@"p.name = %p, copyP.name = %p", p.name, copyP.name);
    @end
    

    출력 결과: p = 0x60000002a080,copyP = 0x600000034020 p.name = 0x60000002f480,copyP.name = 0x600000252f00
    만약 copy 대상에 또 다른 사용자 정의 대상 속성이 있다면 이 대상도 그것의 Person 방법을 실현해야 한다.(코드는 다음과 같습니다.)
    @implementation Dog
    - (id)copyWithZone:(NSZone *)zone {
        Dog *d = [[[self class] allocWithZone:zone] init];
        return d;
    }
    @end
    
    @interface Person : NSObject
    @property (nonatomic, strong) NSString *name;// strong
    @property (nonatomic, assign) NSInteger age;
    @property (nonatomic, strong) Dog *dog;// 
    @end
    
    @implementation Person
    - (id)copyWithZone:(NSZone *)zone {
        Person *p = [[[self class] allocWithZone:zone] init];
        //name , copy , 
        p.name = [self.name mutableCopy];
        p.age = self.age;
        // copy 
        p.dog = [self.dog copy];
        return p;
    }
    @end
    
    @implementation ViewController
    Person *p = [[Person alloc] init];
    p.name = [NSString stringWithFormat:@"%@", @" "];
    p.dog = [[Dog alloc] init];
    Person *copyP = [p copy];
    
    NSLog(@"p = %p, copyP = %p", p, copyP);
    NSLog(@"p.name = %p, copyP.name = %p", p.name, copyP.name);
    NSLog(@"p.dog = %p, copyP.dog = %p", p.dog, copyP.dog);
    @end
    

    출력 결과: p = 0x6000000340c0,copyP = 0x60000003e340 p.name = 0x60000003e1e0,copyP.name = 0x600000445d30 p.dog = 0x60000003e320, copyP.dog = 0x60000003e200
    협의를 체결한 것은 이 종류와 그 하위 클래스에 통일된copyWithZone: 방법을 추가하기 위해서이다.그렇지 않으면 우리는 이 대상의 복사를 실현하기 위해 간단하고 난폭하게 스스로 방법을 쓸 수 있다.예를 들어 우리는 하위 황인종copy을 만들고 다시 쓰기YPerson 방법만 하면 된다.
    @implementation YPerson
    - (id)copyWithZone:(NSZone *)zone {
        YPerson *yp = [super copyWithZone:zone];
        // 
        yp.address = [self.address mutableCopy];
        return yp;
    }
    @end
    
    @implementation ViewController
    YPerson *yp = [[YPerson alloc] init];
    YPerson *copyYP = [yp copy];
    NSLog(@"yp = %p, copyYP = %p", yp, copyYP);
    @end
    

    출력 결과: yp = 0x600000249e40,copyYP = 0x600000249a50

    좋은 웹페이지 즐겨찾기