Как правильно наследовать делегат свойства в Objective-C? - PullRequest
8 голосов
/ 19 марта 2012

При создании подкласса класса я хочу также создать подкласс делегата родительского класса, учитывая, что подкласс теперь имеет дополнительные функции. Каков наилучший способ сделать это? Если бы я просто объявил другое свойство делегата в подклассе с тем же именем, я бы получил предупреждение: «Тип свойства« id »несовместим с типом« id », унаследованным от« ParentClass »

Ответы [ 2 ]

18 голосов
/ 31 января 2013

Данный пример выдает предупреждение:

// Class A
@protocol ClassADelegete;

@interface ClassA : NSObject
@property (nonatomic, weak) id<ClassADelegete> delegate;
@end

@protocol ClassADelegete <NSObject>
- (void)classADidSomethingInteresting:(ClassA *)classA;
@end

// Class B
@protocol ClassBDelegete;

@interface ClassB : ClassA
@property (nonatomic, weak) id<ClassBDelegete> delegate; // Warning here
@end

@protocol ClassBDelegete <ClassADelegete>
- (void)classBDidSomethingElse:(ClassB *)classB;
@end

Два решения, которые удаляют предупреждение:

1) В подклассе поместите определение протокола перед определением класса. Вот что делает UITableViewDelegate в UITableView.h:

// Class B
@class ClassB;

@protocol ClassBDelegete <ClassADelegete>
- (void)classBDidSomethingElse:(ClassB *)classB;
@end

@interface ClassB : ClassA
@property (nonatomic, weak) id<ClassBDelegete> delegate;
@end

2) В подкласс добавьте исходный протокол вместе с новым:

// Class B
@protocol ClassBDelegete;

@interface ClassB : ClassA
@property (nonatomic, weak) id<ClassADelegete, ClassBDelegete> delegate;
@end

@protocol ClassBDelegete <ClassADelegete>
- (void)classBDidSomethingElse:(ClassB *)classB;
@end

Я предполагаю, что (1) работает так, как Apple делает это, Вариант (2) удаляет предупреждение, но я не скомпилировал и не запустил что-либо настроенное таким образом.

1 голос
/ 19 марта 2012

Следуйте примеру NSTableView и NSOutlineView.

NSOutlineView является подклассом NSTableView и определяет собственный протокол для своих dataSource и delegate.

* 1009.*NSTableView объявляет своего делегата следующим образом:
- (void)setDelegate:(id <NSTableViewDelegate>)delegate;
- (id <NSTableViewDelegate>)delegate;

и NSOutlineView:

- (void)setDelegate:(id <NSOutlineViewDelegate>)anObject;
- (id <NSOutlineViewDelegate>)delegate;

Видимо, компилятор более мягок с объявлениями голых методов, чем с объявлениями свойств.

В отличие от NSTable / OutlineView, вы можете захотеть сделать так, чтобы протокол подкласса наследовал от протокола базового класса, например,

 @protocol SpecializedProtocol <BaseProtocol>

... это, вероятно, зависит от ситуации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...