Compiled Chronicles

A software development blog by Angelo Villegas

Clang Language Extensions: instancetype

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] is NSArray, since init has a related result type and its receiver is known to have the type NSArray. 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.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *