Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using instancetype as the return type of a copy in Objective-C?

Using instancetype as a return value of init and related methods is the recommended way to proceed, see the latest clang features. However, what is the best practice w.r.t. the return value of copyWithZone: in the NSCopying protocol (see this thread for previous best practices)? It is not mentioned in the rules for inferring the class from the naming scheme of the methods in the clang article, but I don't see why it should be different than the return value of the alloc method.

Does the type inference not work for copy-methods? Should we still return instancetype or rather the specific class type we actually return?

like image 432
user8472 Avatar asked Oct 10 '13 19:10

user8472


People also ask

What is Instancetype in Objective C?

instancetype. Use the instancetype keyword as the return type of methods that return an instance of the class they are called on (or a subclass of that class). These methods include alloc , init , and class factory methods.

What is Instancetype in Swift?

This is where the compiler steps in to resolve this timeless edge case to the Objective-C type system: instancetype is a contextual keyword that can be used as a result type to signal that a method returns a related result type.


2 Answers

You should NOT use instancetype. The obvious case here is that there is the immutable/mutable distinction -- A copy of an NSMutableString returns an NSString which you should treat as immutable. In that case, the API does not return an instance of the same type as the receiver.

The other reason is that you should match the declaration's signature, as Josh Caswell noted (+1).

Of course, nothing is preventing you from declaring your own protocol with the semantics and signature you desire.

like image 113
justin Avatar answered Oct 22 '22 17:10

justin


You're not declaring copyWithZone:; it's already declared by the protocol, and if your class says it conforms to the protocol, then it also adopts the existing declaration. That declaration uses id as its return type.

You have to write down a return type when you implement the method, of course, but the compiler is using the declaration, not the definition, when it does type checking.

As far as I know, instancetype is "compatible" with id*, so you could write that in your definition, but strictly speaking, I think it would be best to use the exact same type as the declaration.

Therefore, use id.


*I.e., Clang doesn't complain about copyWithZone: being defined with instancetype as its return type.

like image 40
jscs Avatar answered Oct 22 '22 19:10

jscs