Кластер классов с помощью clang: как использовать `__attribute__((objc_method_family(none)))`?
Я хочу реализовать кластер классов (с ARC), но Clang мешает. Вот один метод init, который возвращает конкретный экземпляр другого класса, который является точкой кластеров классов:
@implementation PlaceholderServer
- (Server *) init {
MockServer *concreteServer = [[MockServer alloc] init];
return concreteServer;
}
@end
И лязг жалуется на return
заявление:
warning: incompatible pointer types returning 'MockServer *__strong' from a function with result type 'PlaceholderServer *' [-Wincompatible-pointer-types]
Я понимаю причину этого предупреждения: init
Clang признает принадлежность к init
семейство методов, которые должны возвращать экземпляры реализующего класса (или, возможно, подкласса). Обычно это не тот случай в кластере классов, где конкретный конкретный класс может быть создан в зависимости от условий.
clang предоставляет аннотацию для переопределения автоматического распознавания семейств методов: __attribute__((objc_method_family(FAMILLY)))
где семья может быть одним из alloc
, copy
, init
, mutableCopy
, или же new
, Это также может быть none
, о котором в документации написано: "Если семья none
метод не имеет семейства, даже если в противном случае считается, что он основан на его селекторе и типе."
К сожалению, я не могу заставить это работать в моем случае. Если я добавлю следующую декларацию в @interface
:
- (SGIServer *) init __attribute__((objc_method_family(none)));
Тогда предупреждение не уходит. Если я добавлю атрибут к реализации:
- (Server *) init __attribute__((objc_method_family(none)))
{
MockServer *concreteServer = [[MockServer alloc] init];
return concreteServer;
}
Тогда предупреждение не исчезает, и я также получаю ошибку:
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)))
^
И если я сделаю оба, первоначальное предупреждение не исчезнет, но я получу дополнительное предупреждение:
warning: attributes on method implementation and its declaration must match [-Wmismatched-method-attributes]
Итак, я предполагаю, что упускаю что-то элементарное, но что?
Это с Xcode 4.3.2 или Xcode 4.4DP2.
1 ответ
Не нужно возиться с атрибутами; Вы должны быть в состоянии вместо return (id) concreteServer;
, который переключается на динамическую типизацию.