Кластер классов с clang: как использовать `__attribute __ ((objc_method_family (none)))`? - PullRequest
0 голосов
/ 01 апреля 2012

Я хочу реализовать кластер классов (с ARC), но мешает clang.Вот один метод init, который возвращает конкретный экземпляр другого класса, который является точкой кластеров классов:

@implementation PlaceholderServer
- (Server *) init {
    MockServer *concreteServer = [[MockServer alloc] init];
    return concreteServer;
}
@end

И clang жалуется на оператор return:

warning: incompatible pointer types returning 'MockServer *__strong' from a function with result type 'PlaceholderServer *' [-Wincompatible-pointer-types]

Я понимаю причину этого предупреждения: clang распознает init как принадлежащий к семейству методов init, которые должны возвращать экземпляры реализующего класса (или, возможно, подкласса).Обычно это не так в кластере классов, где конкретный конкретный класс для создания экземпляра может варьироваться в зависимости от любого условия.

clang предоставляет аннотацию для переопределения автоматического распознавания семейств методов: __attribute__((objc_method_family(FAMILLY))), где 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 Ответ

0 голосов
/ 24 мая 2012

Нет необходимости возиться с атрибутами;вместо этого вы должны иметь возможность return (id) concreteServer;, которая переключается на динамическую типизацию.

...