I want to implement a class cluster (with ARC), but clang gets in the way. Here is one init method that returns a concrete instance of another class - which is the point of class clusters:
@implementation PlaceholderServer
- (Server *) init {
MockServer *concreteServer = [[MockServer alloc] init];
return concreteServer;
}
@end
And clang complains on the return
statement:
warning: incompatible pointer types returning 'MockServer *__strong' from a function with result type 'PlaceholderServer *' [-Wincompatible-pointer-types]
I understand the reason for that warning: init
is recognized by clang as belonging to the init
family of methods which are supposed to return instances of the implementing class (or perhaps a subclass). That's typically not the case in a class cluster where the actual concrete class to instantiate can vary depending on whatever condition.
clang provides an annotation to override the automatic recognition of method families: __attribute__((objc_method_family(FAMILLY)))
, where familly can be one of alloc
, copy
, init
, mutableCopy
, or new
. It can also be none
, about which the documentation says: "If family is none
, the method has no family, even if it would otherwise be considered to have one based on its selector and type."
Unfortunately, I can't manage to make it work in my case. If I add the following declaration to the @interface
:
- (SGIServer *) init __attribute__((objc_method_family(none)));
Then the warning doesn't go away. If I add the attribute to the implementation:
- (Server *) init __attribute__((objc_method_family(none)))
{
MockServer *concreteServer = [[MockServer alloc] init];
return concreteServer;
}
Then the warning doesn't go away and I also get an error:
error: method was declared as an 'init' method, but its implementation doesn't match because its result type is unrelated to its receiver type
- (SGIServer *) init __attribute__((objc_method_family(none)))
^
And if I do both, the initial warning doesn't go away, but I get an additional warning:
warning: attributes on method implementation and its declaration must match [-Wmismatched-method-attributes]
So I suppose I am missing something elementary, but what?
This is with Xcode 4.3.2 or Xcode 4.4DP2.
No messing with attributes should be necessary; you should be able to instead
return (id) concreteServer;
, which switches to dynamic typing.