Кластер классов с помощью 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;, который переключается на динамическую типизацию.

Другие вопросы по тегам