Как переопределить свойство суперкласса более конкретными типами? - PullRequest
26 голосов
/ 05 мая 2011

Сценарий
У меня есть ситуация, когда базовый класс с именем AbstractRequest имеет свойство делегата типа id <AbstractRequestDelegate>, объявленное в заголовочном файле:

@property (nonatomic, assign) id <AbstractRequestDelegate> delegate;

Протокол абстрактного делегата содержит несколько обязательных методов, и, как указано словом «абстрактный», оба значения AbstractRequest и AbstractRequestDelegate предназначены для подклассов / расширений.

Одним из примеров этого может быть подкласс ConcreteRequest и расширенный протокол ConcreteRequestDelegates, которые оба добавляют дополнительные методы к абстрактным. Предполагается, что как абстрактный, так и конкретный методы класса могут отправлять сообщения в один назначенный экземпляр делегата.

В определенный момент времени ConcreteRequest хотел бы вызвать метод для делегата, который определен ConcreteRequestDelegate. Поскольку тип делегата - id, компилятор выдаст предупреждение о том, что этот метод может быть не реализован.

ConcreteRequest.m: 38: предупреждение: свойство 'делегат' требует метода '-delegate' будет определено - использовать @synthesize, @dynamic или предоставить реализация метода

Проблема
Это предупреждение оправдано, поскольку свойство все-таки набрано id <AbstractRequestDelegate>. Чтобы это исправить, я хочу прояснить для компилятора, что делегат, назначенный конкретному экземпляру, должен иметь тип id <ConcreteRequestDelegate>. Это звучало совершенно разумно для меня, поэтому я добавил новое свойство в заголовок ConcreteRequest, надеясь переопределить абстрактное:

@property (nonatomic, assign) id <ConcreteRequestDelegate> delegate;

Но именно здесь компилятор не согласен со мной, вероятно, по уважительной причине. Я бы подумал, что это даст предупреждение за переопределение свойства суперкласса неправильным типом, но вместо этого он просто потребует от меня повторного синтеза этого нового свойства. Я не хочу туда идти, потому что тогда у методов суперкласса не будет доступа к тому же свойству делегата.

Вопрос
Есть ли способ повторно объявить свойство в конкретном подклассе с добавленной информацией о типе? Или вы можете заметить ошибку в моем мышлении, потому что, возможно, это довольно распространенная проблема, с которой я до сих пор не сталкивался?

Приветствия
EP.

P.S. Все имена классов и протоколов, представленные в этой работе, являются вымышленными. Любое сходство с реальными именами классов и протоколов, с открытым исходным кодом или запатентовано, является чисто случайным.

Ответы [ 2 ]

11 голосов
/ 07 мая 2011

Предупреждение уже дало правильную подсказку.Я использовал @dynamic в первичном подклассе, и все хорошо.

2 голосов
/ 05 мая 2011

Просто синтезируйте id<ConcreteRequestDelegate>delegate в ConcreteRequest.m, он будет работать нормально ... Это не создаст никаких проблем.

...