sourcecode

복사 구현 시 모범 사례구역 포함:

codebag 2023. 8. 11. 21:48
반응형

복사 구현 시 모범 사례구역 포함:

구현과 관련하여 머릿속에서 몇 가지 사항을 정리하려고 합니다.copyWithZone:다음의 ...에 대하여 누구나 논평할 수 있습니까?

// 001: Crime is a subclass of NSObject.
- (id)copyWithZone:(NSZone *)zone {
    Crime *newCrime = [[[self class] allocWithZone:zone] init];
    if(newCrime) {
        [newCrime setMonth:[self month]];
        [newCrime setCategory:[self category]];
        [newCrime setCoordinate:[self coordinate]];
        [newCrime setLocationName:[self locationName]];
        [newCrime setTitle:[self title]];
        [newCrime setSubtitle:[self subtitle]];
    }
    return newCrime;
}

// 002: Crime is not a subclass of NSObject.
- (id)copyWithZone:(NSZone *)zone {
    Crime *newCrime = [super copyWithZone:zone];
    [newCrime setMonth:[self month]];
    [newCrime setCategory:[self category]];
    [newCrime setCoordinate:[self coordinate]];
    [newCrime setLocationName:[self locationName]];
    [newCrime setTitle:[self title]];
    [newCrime setSubtitle:[self subtitle]];
    return newCrime;
}

001에서:

  1. 클래스 이름을 직접 쓰는 것이 가장 좋습니까?[[Crime allocWithZone:zone] init]아니면 사용할까요?[[[self Class] allocWithZone:zone] init]?

  2. 사용해도 됩니까?[self month]iVars를 복사하거나 iVars에 직접 액세스해야 합니다._month?

  1. 항상 사용해야 합니다.[[self class] allocWithZone:zone]적절한 클래스를 사용하여 사본을 작성하는지 확인합니다.002에 대해 제시한 예는 정확한 이유를 보여줍니다: 하위 클래스에서 호출합니다.[super copyWithZone:zone]그리고 슈퍼 클래스의 인스턴스가 아닌 적절한 클래스의 인스턴스를 되찾기를 기대합니다.

  2. ivar에 직접 액세스하므로 나중에 속성 설정기에 추가할 수 있는 부작용(예: 알림 생성)에 대해 걱정할 필요가 없습니다.하위 클래스는 임의의 메서드를 무시할 수 있습니다.이 예제에서는 ivar당 두 개의 추가 메시지를 보냅니다.다음과 같이 구현하겠습니다.

코드:

- (id)copyWithZone:(NSZone *)zone {
    Crime *newCrime = [super copyWithZone:zone];
    newCrime->_month = [_month copyWithZone:zone];
    newCrime->_category = [_category copyWithZone:zone];
    // etc...
    return newCrime;
}

물론, 아이바를 복사하든, 유지하든, 그냥 할당하든, 세터가 하는 일을 반영해야 합니다.

의 기본 복사 동작copyWithZone:SDK 제공 개체가 있는 메서드는 "허름한 복사"입니다.그 말은 당신이 전화를 하면copyWithZone:NSString개체, 얕은 복사본을 만들지만 깊은 복사본은 만들지 않습니다.얕은 복사와 깊은 복사의 차이점은 다음과 같습니다.

개체의 얕은 복사본은 참조를 원래 배열의 개체에 복사하여 새 배열에 배치합니다.

전체 복사본은 실제로 개체에 포함된 개별 개체를 복사합니다.이것은 각 개별 객체를 전송함으로써 수행됩니다.copyWithZone:사용자 정의 클래스 메소드에 있는 메시지입니다.

IN SHORT : 호출하는 얕은 사본을 얻으려면retain또는strong모든 인스턴스(instance) 변수에 적용됩니다.전화하는 딥 카피를 얻으려면copyWithZone:사용자 정의 클래스의 모든 인스턴스 변수에 대해copyWithZone:실행.이제 선택은 당신의 선택입니다.

딥 카피를 구현하는 이 제품은 어떻습니까?

/// Class Foo has two properties: month and category
- (id)copyWithZone:(NSZone *zone) {
    Foo *newFoo;
    if ([self.superclass instancesRespondToSelector:@selector(copyWithZone:)]) {
        newFoo = [super copyWithZone:zone];
    } else {
        newFoo = [[self.class allocWithZone:zone] init];
    }
    newFoo->_month = [_month copyWithZone:zone];
    newFoo->_category = [_category copyWithZone:zone];
    return newFoo;
}

이것은 제 모델입니다.

#import <Foundation/Foundation.h>
@interface RSRFDAModel : NSObject


@property (nonatomic, assign) NSInteger objectId;

@property (nonatomic, copy) NSString *name;

@property (nonatomic, strong) NSArray<RSRFDAModel *> *beans;


@end


#import "RSRFDAModel.h"

@interface RSRFDAModel () <NSCopying>

@end

@implementation RSRFDAModel 


-(id)copyWithZone:(NSZone *)zone {
    RSRFDAModel *model = [[[self class] allocWithZone:zone] init];

    model.objectId = self.objectId;
    model.name = self.name;
    model.beans = [self.beans mutableCopy];

    return model;
}

@end

언급URL : https://stackoverflow.com/questions/9907154/best-practice-when-implementing-copywithzone

반응형