Objective-C Language Classes and Objects The "instancetype" return type


Objective-C supports a special type called `instancetype that can only be used as type returned by a method. It evaluates to the class of the receiving object.

Consider the following class hierarchy:

@interface Foo : NSObject

- (instancetype)initWithString:(NSString *)string;


@interface Bar : Foo

When [[Foo alloc] initWithString:@"abc"] is called, the compiler can infer that the return type is Foo *. The Bar class derived from Foo but did not override the declaration of the initializer. Yet, thanks to instancetype, the compiler can infer that [[Bar alloc] initWithString:@"xyz"] returns a value of type Bar *.

Consider the return type of -[Foo initWithString:] being Foo * instead: if you would call [[Bar alloc] initWithString:], the compiler would infer that a Foo * is returned, not a Bar * as is the intention of the developer. The instancetype solved this issue.

Before the introduction of instancetype, initializers, static methods like singleton accessors and other methods that want to return an instance of the receiving class needed to return an id. The problem is that id means "an object of any type". The compiler is thus not able to detect that NSString *wrong = [[Foo alloc] initWithString:@"abc"]; is assigning to a variable with an incorrect type.

Due to this issue, initializers should always use instancetype instead of id as the return value.