2012-03-19 19 views
7

Al crear una clase de subclases, también deseo crear una subclase de un delegado de la clase primaria dado que la subclase ahora tiene funcionalidad adicional. ¿Cuál es la mejor manera de hacer esto? Si tan sólo declaro otra propiedad delegado en la subclase con el mismo nombre que obtendría una advertencia "Tipo de propiedad 'id' es incompatible con el tipo 'id' heredado de 'ParentClass'¿Cómo subclonar apropiadamente una propiedad de delegado en Objective-C?

Respuesta

1

Siga el ejemplo de NSTableView y NSOutlineView.

NSOutlineView es una subclase de NSTableView, y define su propio protocolo para su dataSource y delegate

NSTableView declara su delegado de esta manera:.

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

y NSOutlineView:

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

Al parecer, el compilador es más indulgente con declaraciones de métodos desnudas de lo que es con declaraciones de bienes.

A diferencia de NSTable/OutlineView, es posible que desee hacer que el protocolo de la subclase herede del protocolo de la clase base, p. Ej.

@protocol SpecializedProtocol <BaseProtocol> 

... probablemente depende de la situación.

+0

Fui con la última ruta (subclase del protocolo delegado después de la subclasificación de la clase principal), pero no pude declarar otra propiedad delegada sin desencadenar el error del compilador. ¿Las declaraciones de métodos que mencionaste son la única forma de hacer feliz al compilador? – Boon

+0

No conozco otra forma de hacerlo. –

15

dado este ejemplo que produce la advertencia:

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

dos soluciones que eliminan la advertencia son.

1) En la subclase, coloque la definición del protocolo antes de la definición de la clase. Esto es lo que UITableViewDelegate en UITableView.h hace:

// Class B 
@class ClassB; 

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

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

2) En la subclase, agregue el protocolo original junto con el nuevo:

// Class B 
@protocol ClassBDelegete; 

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

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

Asumo (1) funciona como manzana hacerlo de esta manera, La opción (2) elimina la advertencia pero no he compilado y ejecuto nada configurado de esta manera.

Cuestiones relacionadas