2013-05-25 1 views
-2

내장 된 이니셜 라이저에서 허용하지 않는 방식으로 Cocoa 컬렉션을 생성하는 클래스 메서드가 있습니다. 제한된 이니셜 라이저 기능으로 인해 콜렉션의 가변 버전을 사용하여 실제로 빌드해야합니다. 여기 NS{Mutable}IndexSet에 대한 예입니다 :instancetype을 사용하는 클래스 생성자에서 하위 클래스를 반환해도 괜찮습니까?

@implementation NSIndexSet (WSSNonContiguous) 

+ (instancetype)WSSIndexSetFromMask:(NSUInteger)mask 
{ 
    NSMutableIndexSet * set = [NSMutableIndexSet indexSet]; 

    for(NSUInteger i = 0; i < (sizeof(NSUInteger) * 8); i++){ 
     if(mask & (1l << i)){ 
      [set addIndex:i]; 
     } 
    } 

    return set; 
} 

내 반환 형식은 때때로 여기에 거짓말 - 사용자가 불변의 버전을 요청 여부, 반환되는 가변 수집은 항상있다.

이런 경우에는 instancetype을 사용하는 것이 여전히 적합합니까? 아니면 id으로해야합니까?

// Ick? 
return [[self alloc] initWithIndexSet:set]; 

는 불변의 사본이 호출이 +[NSIndexSet WSSIndexSetFromMask:] 때 반환되어 있는지 확인하기 위해 : 나는 instancetype를 사용하는 경우, 나는 또한 명시 적으로해야 컬렉션을 다시 만드는?

답변

1

다 괜찮 :

NSIndexSet *set = [[NSIndexSet WSSIndexSetFromMask:0] addIndex:0]; 

No visible @interface for 'NSIndexSet' declares the selector 'addIndex:' 

instancetype

은 당신이 하위 유형에도 입력 수신기의 인스턴스를 반환하는 것이, 보낸 사람에게 말한다. 보낸 사람의 경우 NSIndexSet 클래스 개체에 보내기 때문에 NSIndexSet입니다.

누군가가 반환 형식을보고 하위 클래스를보고이 정보에서 이점을 얻는 방식으로 인트로 검사가 이루어집니다. 계약은 반환 유형으로 빌드되며이 경우 NSIndexSet입니다.

+1

« 'instancetype'은 송신자에게 수신자 유형이 서브 타입 일지라도 반환한다는 것을 말합니다.»이것이 문제의 핵심이라고 생각합니다. 그런 다음 결과를 mutable으로 처리하는 것이 프로그래머 오류이므로'[NSIndexSet WSSIndexSetFromMask : 0];의 경우 불변으로 세트를 재구성하는 것이 불필요하다고 생각하십니까? –

+0

1. 예, 이에 대해 설명되어 있습니다. 두 번째 문제가있다. 그러나 코드에는 없다. (!) : Cocoa의 $ $ collection에 subtype $ mutableCollection이 있기 때문에, 리시버 (!)는 콜렉션 객체를 반환하지 않고 반환 된 콜렉션의 내용을 변경할 수있다. 발신자가 그 사실을 알릴 기회. NSSet도 NSSet이 될 수 있습니다. 아마도 애플이 Liskov와 분리되기 때문에 컬렉션의 변종 컬렉션 하위 클래스를 만드는 것은 좋은 결정이 아니었을 것입니다. 이 경우 보낸 사람이 반환 된 개체를 복사하는 작업입니다. (어느 것이 변경 불가능한 경우 0- 비용에 가깝습니다.) –

+0

1. 명확성이 누출되지 않습니다. 반환 유형 *은 * instancetype aka NSIndexSet입니다. NSMutableIndexSet *은 Liskov의 NSIndexSet입니다. 2. Donald Knuth. –

관련 문제