Objective-C: instancetype 키워드
Objective-C에서 alloc
, init
같은 객체를 할당하고 초기화하는 메소드들은 제네릭 타입인 id
형을 리턴 형으로 하는 규칙convention을 사용한다.
@interface NSObject
+ (id)alloc;
- (id)init;
@end
제네릭 타입을 리턴 형으로 사용하니 생성된 객체를 다른 형type에 대입하거나, 초기화 과정에서 잘못된 메소드의 호출을 컴파일 시에 미리 발견할 수 없다는 문제가 생긴다.
// No errors at compile time.
[[[NSArray alloc] init] undefinedMethod];
또한, Xcode와 같은 IDE 툴의 자동 완성 기능이 형을 추론하기 힘들어 편집 시에 적절한 메소드를 제안하기 어렵다는 점도 있다. 이런 점들을 보완하고 형 안정성type safety을 향상하기 위해 instancetype
키워드가 추가되었다.
Objective-C에서 특정한 이름(alloc
, init
등)을 가진 메소드는 항상 그 객체의 형을 가진 인스턴스를 리턴하는데, 이것을 “연관된 리턴 형related result type을 가진다"고 말한다. 예를 들어,
NSArray *array = [NSArray alloc];
여기서 alloc
메소드의 리턴 형은 id
형이지만 이 메소드는 암묵적으로 연관된 리턴 형을 가지고 있으므로, 실제로 할당되어 리턴된 객체는 NSArray *
형이다.
연관된 리턴 형을 가진 메소드는 컴파일러(Clang)에 의해 추론될 수 있는데, 다음의 조건을 가지는 메소드의 리턴 형(id
)은 컴파일 시에 instancetype
으로 승격promotion되어 형 안정성을 높인다.
- 첫 단어가
alloc
또는new
로 시작하는 클래스 메소드이거나 - 첫 단어가
autorelease
또는init
,retain
,self
로 시작하는 인스턴스 메소드
이 조건에 해당하지 않는 메소드를 만들 때에는 리턴 형을 명시적으로 instancetype
형으로 선언해야 한다.
참고로, OS X 10.10 Yosemite와 iOS 8 SDK부터 위 조건에 해당하는 리턴 형 id
는 모두 명시적으로 instancetype
형으로 선언된다.
References
- Adopting Modern Objective-C (iOS Developer Library)
- Related result types (Clang Language Extensions)