내장 된 이니셜 라이저에서 허용하지 않는 방식으로 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
를 사용하는 경우, 나는 또한 명시 적으로해야 컬렉션을 다시 만드는?
« 'instancetype'은 송신자에게 수신자 유형이 서브 타입 일지라도 반환한다는 것을 말합니다.»이것이 문제의 핵심이라고 생각합니다. 그런 다음 결과를 mutable으로 처리하는 것이 프로그래머 오류이므로'[NSIndexSet WSSIndexSetFromMask : 0];의 경우 불변으로 세트를 재구성하는 것이 불필요하다고 생각하십니까? –
1. 예, 이에 대해 설명되어 있습니다. 두 번째 문제가있다. 그러나 코드에는 없다. (!) : Cocoa의 $ $ collection에 subtype $ mutableCollection이 있기 때문에, 리시버 (!)는 콜렉션 객체를 반환하지 않고 반환 된 콜렉션의 내용을 변경할 수있다. 발신자가 그 사실을 알릴 기회. NSSet도 NSSet이 될 수 있습니다. 아마도 애플이 Liskov와 분리되기 때문에 컬렉션의 변종 컬렉션 하위 클래스를 만드는 것은 좋은 결정이 아니었을 것입니다. 이 경우 보낸 사람이 반환 된 개체를 복사하는 작업입니다. (어느 것이 변경 불가능한 경우 0- 비용에 가깝습니다.) –
1. 명확성이 누출되지 않습니다. 반환 유형 *은 * instancetype aka NSIndexSet입니다. NSMutableIndexSet *은 Liskov의 NSIndexSet입니다. 2. Donald Knuth. –