2011-03-05 10 views
10

Parece que estoy recibiendo un nuevo error al usar el Compilador LLVM 2.0, que no he tenido antes.Propiedades de anulación que se ajustan a los protocolos

Tengo un protocolo llamado DTGridViewDelegate definido como:

@protocol DTGridViewDelegate <UIScrollViewDelegate>

tengo una propiedad llamada delegate on DTGridView (una subclase de UIScrollView, que en sí misma tiene una propiedad delegate). Esta se define como:

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

Ahora el mensaje que recibo es:

DTGridView.h:116:63: error: property type 'id<DTGridViewDelegate>' is incompatible with type 'id<UIScrollViewDelegate>' inherited from 'UIScrollView'

Como había dicho que el DTGridViewDelegate se ajusta a UIScrollViewDelegate, pensé que esto estaría bien para anular esta propiedad de esta manera, y de hecho este es el primer compilador que sugiere que hay un problema.

He fijado el error al declarar la propiedad como tal:

@property (nonatomic, assign) IBOutlet id<DTGridViewDelegate, UIScrollViewDelegate> delegate;

Me pregunto si esto es un problema de compilador?

Respuesta

8

Su configuración es similar a la utilizada en el caso de UITableView que hereda de UIScrollView. El protocolo UITableViewDelegate hereda del protocolo UIScrollViewDelegate.

puedo configurar los siguientes elementos que compila bien:

// .h 
@protocol ParentClassDelegate 
-(NSString *) aDelegateMethod; 
@end 

@interface ParentClass : NSObject { 
    id delegate; 
} 
@property(nonatomic, assign) IBOutlet id <ParentClassDelegate> delegate; 
@end 

//.m 
@implementation ParentClass 
@synthesize delegate; 

-(id) delegate{ 
    return @"Parent delegate"; 
}//-------------------------------------(id) delegate------------------------------------ 

-(void) setDelegate:(id)someObj{ 
    delegate=someObj; 
}//-------------------------------------(id) setDelegate------------------------------------ 
@end 

//.h 
@protocol ChildClassDelegate <ParentClassDelegate> 
-(NSArray *) anotherDelegateMethod; 
@end 

@interface ChildClass : ParentClass{ 
} 
@property(nonatomic, retain) IBOutlet id <ChildClassDelegate> delegate; 
@end 

//.m 
@implementation ChildClass 
//@synthesize delegate; 

-(id) delegate{ 
    return @"childDelegate"; 
}//-------------------------------------(id) delegate------------------------------------ 

-(void) setDelegate:(id)someObj{ 
    delegate=someObj; 
}//-------------------------------------(id) setDelegate------------------------------------ 

@end 
No

seguro de lo que está causando el problema. Quisiera señalar que en la cabecera del protocolo UITableViewDelegate parece:

@protocol UITableViewDelegate<NSObject, UIScrollViewDelegate> 

... así que tal vez el compilador le gustan las cosas más explícito veces.

Sugeriría una limpieza y compilación. Eso resuelve muchos problemas.

+0

Active las advertencias más estrictas de http://boredzo.org/blog/archives/2009-11-07/warnings usando el guión de Wolf aquí: http://rentzsch.tumblr.com/post/237349423/hoseyifyxcodewarnings-scpt. Lo cual probablemente explica por qué no está viendo la advertencia/error. –

+0

Sin embargo, tiene toda la razón, olvidé UITableViewDelegate, ¡que en primer lugar, deduje ese código!Me parece que la primera forma no debería arrojarle una advertencia. Además, me parece extraño que UITableViewDelegate diga que se ajusta a NSObject cuando también se ajusta a UIScrollViewDelegate, que a su vez se ajusta a NSObject. –

+3

Así que después de un debate adicional con @MikeAbdullah, resulta que necesitaba poner las declaraciones de protocolo antes de la interfaz de clase. El @protocol DTGridViewDelegate no decía que se ajustaba a cuando el compilador alcanzó mi declaración de propiedad. –

4

Dado que no existe una especificación formal de lenguaje Objective-C, es imposible determinar si el compilador se comporta correctamente. Todo lo que podemos decir es que el gcc de Apple no parece tener un problema con el escenario anterior, aunque es conceptualmente incorrecto ya que puede romper Liskov substitution, ya que delegate es covariant desde UIScrollView hasta DTGridView (aunque la covarianza es un problema similar). ¿Qué pasaría si pasara un DTGridView para codificar esperando un UIScrollView, que luego procedió a establecer delegate en un objeto que se ajustaba al UIScrollViewDelegate pero no al ?

+0

Eso es perfectamente cierto. Lo que me parece extraño es que, en ambos sentidos, he declarado al delegado, esto se romperá como usted describe, pero el compilador solo advierte contra uno de ellos. –

Cuestiones relacionadas