Objective-C is a rapidly evolving language faster than many other. ARC, object literals, subscripting, blocks: in the span of just three years, this is just an example of how fast it grows. One of the latest addition to ObjC
is instancetype
.
Clang adds a keyword instancetype
that, as far as I can see, replaces id
as a return type in alloc
and init
.
Is there a benefit to using instancetype instead of id?
Yes, there are benefits to using instancetype
in all cases where it applies. Use instancetype
whenever it’s appropriate, which is whenever a class returns an instance of that same class. In Objective-C, conventions aren’t just a matter of coding best-practices, they are implicit instructions to the compiler.
According to Cocoa conventions, Objective-C methods with certain names (init
, alloc
, etc.) always return objects that are an instance of the receiving class’s type. These methods are said to have a related result type.
As explained in here:
The type of the expression
[[NSArray alloc] init]
isNSArray
, since init has a related result type and its receiver is known to have the typeNSArray
. If neither alloc nor init had a related result type, the expressions would have had type id, as declared in the method signature.
With instancetype
, the compiler will correctly infer that the result of alloc
and init
is an instance of an NSArray
while using an id
will just return a generic object.
A method with a related result type can be declared by using the type instancetype
as its result type. instancetype
is a contextual keyword that is only permitted in the result type of an Objective-C method, e.g.
@interface ClassName : SuperClass
+ (instancetype)methodName:(id)parameter;
@end
For a convenience constructor, you should always use instancetype
; The compiler does not automatically convert id
to instancetype
but if you make it an instancetype
, the compiler knows what type of object the method returns.
Now let’s say we have a whole class…
@interface ClassName : SuperClass
+ (instancetype)methodName:(id)parameter;
+ (ClassName *)anotherMethodName:(id)parameter;
@end
…and we added 2 new subclasses, SubclassName
and AnotherSubclassName
, that is a subclass of ClassName
, sending a message using +methodName:
is guaranteed an instance of SubclassName
, but +anotherMethodName:
will return an instance of ClassName
instead.
Conclusion
Unless you are intentionally writing codes for old compilers, you should use instancetype
when appropriate. You should think twice before writing a message that returns id
.
There are certain cases where you need to return id
, but you’ll probably use instancetype
much more frequently. Look, even NSString
started to use instancetype
.
Leave a Reply