2013-10-31 6 views
5

하나는 종종 불변 클래스는 다음과 같은 방법으로 매우 효율적으로 copyWithZone를 구현할 수 있다는 읽변경 가능한 하위 클래스가있는 불변 클래스의 경우 copyWithZone에서 [self retain]을 반환하는 것이 안전하고 좋은 방법일까요?

- (id) copyWithZone:(NSZone*)zone 
{ 
    return [self retain]; 
} 

그 구현 뒤에 아이디어는 분명하다 : 는 원본과 사본 모두 불변의 인스턴스이며, 그들은 항상 정확히해야합니다 동일한 내용이므로 원본을 유지하고 복사 오버 헤드를 피하여 두 저장소가 동일한 저장소를 가리 키지 않는 이유는 무엇입니까?

그러나 변경 가능한 하위 클래스가 있으면 어떻게됩니까?

- (id) copyWithZone:(NSZone*)zone 
{ 
    MyClass* myCopy = [super copyWithZone:zone]; 
    myCopy->myMember = [myMember copyWithZone:zone]; 
    return myCopy; 
} 

그러나 이것은 위의 무엇을 의미 하는가 : 서브 클래스는 기본 클래스의 구현 세부 사항에 대해 걱정하지 않는 깨끗한 아키텍처와 의 가변 서브 클래스는이 방법으로 copyWithZone을 구현하기 위해 괜찮을 copyWithZone의 슈퍼 클래스 구현? 하위 클래스는 변경할 수 있으므로 여전히 사본은 변경할 수 없지만 원본은 변경할 수 있지만 하위 클래스 copyWithZone은 자체 유지 된 인스턴스에서 작동합니다. self 및 myCopy는 둘 다 동일한 인스턴스를 가리 킵니다. 따라서 나중에 mutableOriginal.myMember의 값을 변경하면 immutableCopy.myMember도 변경됩니다. 이는 일반적인 오류 일뿐입니다.

그래서 불변 클래스가 다음과 같은 방법으로 copyWithZone을 더 잘 구현하지 않아야합니까?

- (id) copyWithZone:(NSZone*)zone 
{ 
    if([[self class] isMemberOfClass:[MyBaseClass class]]) 
     return [self retain]; 
    else 
    { 
     MyBaseClass* myCopy = [[self alloc] init]; 
     myCopy->myBaseMember = [myBaseMember copyWithZone:zone]; 
     return myCopy; 
    } 
} 
+2

아닙니다. 목록에있는 방법 중 하나를 따르는 '사본'을 구현해야한다고 생각하지 않습니다. 복사는 매우 내재적입니다. '[super copy]'를 호출하지 말고, 필요하다면 깨끗하고 새로운 인스턴스를 할당하는 것이 좋습니다. –

답변

3

가장 좋은 방법은 변경 불가능한 수퍼 클래스에 initWithMyImmutableObject 초기화 프로그램을 사용하는 것입니다. 귀하의 하위 클래스는 단지

- (id) copyWithZone:(NSZone*)zone { 
    return [[[self superclass] alloc] initWithMyImmutableObject:self] 
} 

와 속성의 실제 복사 복사 할 필요가있는 모든 개인 회원에 액세스 할 수 있습니다 귀하의 슈퍼 클래스의 방법으로 이루어집니다 그 방법을 NSCopying을 구현할 수 있습니다.