2009-04-09 8 views
69

Si quiero extender una clase como AVAudioPlayer, ¿cuál es la mejor manera de agregar también otro método a AVAudioPlayerDelegate? ¿Hago una categoría para eso, lo extiendo? Si lo extiendo, ¿entonces también tengo que asegurarme de sobrescribir el eliminador/eliminador de delegados real? ¿Cómo extendería el protocolo? A continuación me da erroresCómo extender protocolos/delegados en Objective-C



@protocol AudioTrackDelegate : AVAudioPlayerDelegate { 
    - (void)foo; 
} 
@end 

@interface AudioTrack : AVAudioPlayer { 
} 
@end 

Respuesta

125

La sintaxis para crear un protocolo que implementa otro protocolo es como tal:

@protocol NewProtocol <OldProtocol> 
- (void)foo; 
@end 

Si desea llamar a un método en el NewProtocol en un puntero escrito como OldProtocol que pueda o bien llamar respondsToSelector:

if ([object respondsToSelector:@selector(foo)]) 
    [(id)object foo]; 

o definir métodos stub como una categoría en NSObject:

@interface NSObject (NewProtocol) 
- (void)foo; 
@end 
@implementation NSObject (NewProtocol) 
- (void)foo 
{ 
} 
@end 
+0

Si creo un protocolo que implemente otro protocolo ... ¿Hay algo más que deba hacer para asegurarme de que los métodos 'OldProtocol' se activan? ?porque para mí estoy haciendo que el nuevo protocolo se active pero todos los existentes ya no están – dizy

+10

A protocols no tiene métodos, tiene definiciones de métodos; es decir, describe el nombre, los argumentos y los tipos de devolución que una clase debe tener para considerarse "conformes" a dicho protocolo. Por su comentario/pregunta, estoy apostando a que se olvida de llamar a [super setDelegate: value] en su -setDelegate: – rpetrich

+0

usando este enfoque que no expone los nuevos métodos del protocolo, eche un vistazo a mi respuesta de la manera más clara – Kappe

11

Recuerde un protocolo añade ningún código para la aplicación compilada - que sólo refuerza el hecho de que su clase debe implementar los métodos para ser considerado "conforme" con el protocolo. Un buen uso de esto sería para generar un grupo de clases con toda la misma forma de operar: <printable> o <serialized>, etc. Por lo que podría crear un protocolo <plays> por ejemplo:

@protocol plays 
    - (void) play; 
    - (NSString *) type; 
@end 

Y a continuación, una clase que se ajusta a <plays> DEBE implementar los métodos play y type. Si no lo hace, el compilador emite una advertencia, pero compila la clase de todos modos. En el código que comprueba si un objeto se conforma con un protocolo con el siguiente código:

if ([obj conformsTo: @protocol(plays)]) { 
    [obj play]; 
} 

Una categoría realmente añade nuevos métodos dinámicamente a su clase. Estos métodos son accesibles globalmente para el tiempo de ejecución como selectores y pueden llamarse por nombre como en @selector(foo) y [object foo:bar];

El propósito de una categoría es agregar un código nuevo especial a una clase incluso si no tiene el código fuente para esa clase. Puede haber problemas de seguridad y podría crear pérdidas de memoria en clases, etc.

En su caso, tal vez, en un archivo separado AVAudioPlayerDelegate_TrackOps.m

#import "AVAudioPlayerDelegate.h" 
@implementation AVAudioPlayerDelegate (TrackOps) 

- (NSObject *) foo { 
    // do foo stuff; 
    return bar; 
} 

@end 

Ponerlo como una categoría de NSObject hace todas las clases responden a foo . Foo puede ser un método independiente Objc_perform_selector(@selector(foo)) también.

Conclusión: use una categoría para agregar un método rápido a una clase, protocolos para aplicar implementaciones de métodos y subclases para especializar clases existentes (cosas como agregar variables miembro o nuevas funcionalidades importantes). Las categorías también pueden usarse para anular un método o dos cuando una subclase no es necesaria y no se desea, pero generalmente si desea agregar funcionalidad a una clase, crea una subclase. Para obtener más ejemplos, ideas, otra información general sobre este tema, siempre está el Apple introduction to Objective-C

+0

¿Puede explicar cómo agregar una categoría a un protocolo? Creo que algo anda mal con la sintaxis de lo que escribiste. Gracias – dizy

Cuestiones relacionadas