Can someone please explain to me (in simple terms) why an instancetype
is used in Objective-C?
- (instancetype) init {
self = [super init];
if (self) {
// Custom initialization
}
return self;
}
Back in the old days, initialisers just returned an object of type id
(any object).
With normal initialisers (those that begin with "init", "alloc" or "new"), this wasn't usually a problem. The compiler would automatically infer the type that it returned and therefore restrict any method calls on the object to the instance methods of that class.
However, this was a problem with static convenience initialisers or "factory methods" that didn't necessarily follow the same naming convention - therefore it was unable to apply the same type safety.
This means that with a class like this:
@interface Foo : NSObject
+(id) aConvenienceInit;
@end
The compiler would accept code like this:
NSArray* subviews = [Foo aConvenienceInit].subviews;
Why? Because the returned object could be any object, so if you try and access a UIView
property - there's no type safety to stop you.
However, now with instancetype
, the result you get back is of type of your given instance. Now with this code:
@interface Foo : NSObject
+(instancetype) aConvenienceInit;
@end
...
NSArray* subviews = [Foo aConvenienceInit].subviews;
You'll get a compiler warning saying that the property subviews
is not a member of Foo*
:
Although it's worth noting that the compiler will automatically convert the return type from id
to instancetype
if your method begins with "alloc", "init" or "new" - but nonetheless using instancetype
wherever you can is a good habit to get into.
See the Apple docs on instancetype
for more info.