2012-03-19 15 views
7

W podklasach klasy, chcę również podklasy delegata klasy nadrzędnej, ponieważ podklasa ma teraz dodatkową funkcjonalność. Jaki jest najlepszy sposób na zrobienie tego? Jeżeli po prostu zadeklarować inną właściwość delegata w podklasie o tej samej nazwie, że dostanę ostrzeżenie „typ obiektu«id»jest niezgodny z typem«id»odziedziczony«ParentClass»Jak prawidłowo podklasować właściwość delegata w Objective-C?

Odpowiedz

1

śladem NSTableView i NSOutlineView.

NSOutlineView jest podklasą NSTableView i definiuje swój własny protokół ze swojej dataSource i delegate

NSTableView deklaruje jego delegat w ten sposób:.

- (void)setDelegate:(id <NSTableViewDelegate>)delegate; 
- (id <NSTableViewDelegate>)delegate; 

i NSOutlineView:

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

Najwyraźniej kompilator jest bardziej wyrozumiały gołymi deklaracji metody niż to z deklaracji majątkowych.

W przeciwieństwie do NSTable/OutlineView, możesz chcieć, aby protokół klasy podrzędnej dziedziczył z protokołu klasy bazowej, np.

@protocol SpecializedProtocol <BaseProtocol> 

... prawdopodobnie zależy to od sytuacji.

+0

Poszedłem z tą drugą trasą (podklasa, protokół delegata po podklasie głównej klasy), ale nie udało się zadeklarować innej właściwości delegata bez wywoływania błędu kompilatora. Czy deklaracje metod, które wymieniłeś, są jedynym sposobem na uszczęśliwienie kompilatora? – Boon

+0

Nie znam innego sposobu, aby to zrobić. –

15

Biorąc pod uwagę ten przykład, który generuje ostrzeżenie:

// 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 

dwa rozwiązania, które usuwają ostrzeżenia są.

1) W podklasie umieść definicję protokołu przed definicją klasy. To co UITableViewDelegate w UITableView.h robi:

// Class B 
@class ClassB; 

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

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

2) W podklasie, należy dodać oryginalny protokół wraz z nowym:

// Class B 
@protocol ClassBDelegete; 

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

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

Zakładam (1) działa jak jabłko zrobić to w ten sposób, Opcja (2) usuwa ostrzeżenie, ale nie skompilowałem i nie uruchomiłem niczego w ten sposób.