Протокол наследования в Objective C - PullRequest
5 голосов
/ 25 марта 2011

У меня есть проект, в котором есть протокол, класс, реализующий этот протокол, и подкласс класса реализации.Это наше производственное приложение.

@protocol ProductionProtocol<NSObject>
@property (nonatomic, retain) NSString *role;
@end

@interface BaseProduction : NSObject<ProductionProtocol>
NSString *role;
@end

@implementation BaseProduction
@synthesize role;
@end

@interface Production : BaseProduction
@end

@implementation Production
@end

У меня также есть приложение для проверки концепции (POC), которое реализовано в виде отдельного проекта, включающего производственное приложение.В приложении POC у меня есть протокол, который расширяет производственный протокол, и класс, который расширяет производственный класс.

@protocol POCProtocol<ProductionProtocol>
-(void)cancel;
@end

@interface POC : Production<POCProtocol>
@end

@implementation POC
-(void)cancel{...}
@end

Обратите внимание, что в ProductionProtocol у меня есть роль NSString, которая объявлена ​​и реализована в интерфейсе / классе BaseProduction.в POC у меня есть метод 'cancel', который объявлен в протоколе, но не в интерфейсе / классе.

Итак, вот мой вопрос: с моей структурой класса, настроенной такэто предупреждение:

Property 'role' requires method '-role' to be defined - use @synthesize, @dynamic or provide a method implementation

Я не понимаю, почему я получаю это предупреждение.Поскольку синтезированные свойства находятся в базовом классе, они должны быть доступны для класса POC - и быстрый тест, кажется, подтверждает, что они есть.Так что я тут делаю не так?

Ответы [ 2 ]

11 голосов
/ 25 марта 2011

Не существует официального определения языка для Objective-C, но согласно Apple :

Когда класс принимает протокол, он должен реализовать требуемые методы, которые протокол объявляет, как уже упоминалось ранее.Кроме того, он должен соответствовать любым протоколам, включенным в принятый протокол.Если встроенный протокол включает в себя еще другие протоколы, класс также должен соответствовать им.Класс может соответствовать встроенному протоколу, используя любой из этих методов:

  • Реализация методов, которые протокол объявляет
  • Наследование от класса, который принимает протокол и реализует методы

Однако в сообщениях говорится, что GCC не распознает, что свойство находится во встроенном протоколе и реализовано в суперклассе.Вы можете изменить свой компилятор на Clang, который, как сообщается, обрабатывает это указанным способом, или вы можете просто использовать @dynamic, чтобы сообщить компилятору, что реализация свойства будет предоставлена ​​во время выполнения (в данном случае, наследованием).из суперкласса).

1 голос
/ 25 марта 2011

[XCode 3.2]

Ошибка компилятора заключается в реализации наследования протокола. В примере при компиляции POC есть два пути к ProductionProtocol:

  1. POC -> Production -> BaseProduction -> ProductionProtocol
  2. POC -> POCProtocol -> ProductionProtocol

Это сбивает с толку GCC 4.2, это не смущает Clang (LLVM 1.6, XCode 3.2).

Если вы измените POCProtocol на:

@protocol POCProtocol//<ProductionProtocol>

ошибка исчезнет.

Вы можете просто закомментировать наследование от протокола к протоколу и оставить TODO для удаления после исправления компилятора.

Мне кажется, что это ошибка классического писателя компилятора, или, может быть, кто-то запутался в семантике .NET (где вы можете повторно реализовать интерфейсы (протоколы в Obj-C) в цепочке наследования).

@ danyowdee предлагает вам подать отчет об ошибке, хотя, поскольку его нет в Clang (я не запустил свой консалтинговый XCode 4 для тестирования его компиляторов), я подозреваю, что вряд ли это будет высоким приоритетом для исправления .. .

...