2010-01-05 11 views
50

Me preguntaba si alguien puede explicar qué son los protocolos informales en Objective C? Intento entenderlo en la documentación de Apple y en algunos otros libros, pero mi cabeza todavía está dando vueltas, así que realmente lo apreciaré si alguien puede explicar con el ejemplo.Protocolo Informal En objetivo-C?

Gracias.

Respuesta

58

Un protocolo informal era, como dijo Jonnathan, típicamente una categoría declarada en NSObject sin aplicación correspondiente (lo más a menudo - no era el que raro que no proporcionan implementaciones ficticias en NSObject).

A partir de 10.6 (y en el SDK de iPhone), este patrón ya no se utiliza. En concreto, lo que fue declarado como sigue en 10.5 (y anteriores):

@interface NSObject(NSApplicationNotifications) 
- (void)applicationWillFinishLaunching:(NSNotification *)notification; 
... 
@interface NSObject(NSApplicationDelegate) 
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; 
... 

ahora se declara como:

@protocol NSApplicationDelegate <NSObject> 
@optional 
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; 
... 
- (void)applicationWillFinishLaunching:(NSNotification *)notification; 
... 

Es decir, protocolos informales están declarados como @protocol s con un montón de @optional métodos .

En cualquier caso, un protocolo informal es un conjunto de declaraciones de métodos mediante el cual puede implementar opcionalmente los métodos para cambiar el comportamiento. Normalmente, pero no siempre, las implementaciones del método se proporcionan en el contexto de la delegación (una fuente de datos de la vista de tabla debe implementar un puñado de métodos requeridos y, opcionalmente, puede implementar algunos métodos adicionales, por ejemplo).

4

Todo un protocolo informal es una categoría en alguna clase (a menudo NSObject) que indica la interfaz para el protocolo. AppKit usa esto mucho para su delegación.

Una subclase que escriba puede implementar estos métodos. La diferencia entre esto y un protocolo formal es que los protocolos formales se declaran usando la notación @protocol ... @end. No se verifica si una clase implementa un protocolo informal dado.

Casi siempre uso protocolos formales, pero supongo que un protocolo informal es útil si desea proporcionar un comportamiento predeterminado (simplemente proporcione una implementación para su categoría que puede ser anulada).

+0

Así que es sobre lo "subclases" y luego ponerlas en práctica? Estaba intentando la sintaxis de . – itsaboutcode

9

Uno de los ejemplos comunes dados de protocolos informales es definir callbacks. Supongamos que está utilizando una biblioteca que le permite descargar algo en segundo plano. Esta biblioteca le permite registrar un objeto de devolución de llamada para ser llamado cuando se complete.

- (void)download:(NSURL*)url whenComplete:(id)callback 

Cuando la descarga se haya completado, se llama a un método en particular en el objeto de devolución de llamada:

- (void)downloadComplete:(NSURL*)url 

Por supuesto, no hay ninguna garantía de que el objeto de devolución de llamada en realidad implementa este método. Los protocolos informales proporcionan implementaciones triviales de estos métodos en NSObject, usando una categoría. Como resultado, todos los objetos en el sistema responderán al método downloadComplete:, aunque no harán nada en respuesta a ese método de forma predeterminada. Las clases que reemplazan el método downloadComplete: pueden proporcionar una funcionalidad más útil.

Hasta ahora, puede lograr lo mismo con un protocolo formal. Sin embargo, los protocolos informales le permiten tener métodos opcionales. Una clase que implementa un protocolo formal debe proporcionar una implementación para cada método en el protocolo. Una clase que implementa un protocolo informal puede omitir la implementación de cualquier método; ya ha heredado una implementación de NSObject.

Desde Objective-C 2.0, los protocolos formales pueden contener métodos opcionales. Además, Apple podría estar alejándose de los protocolos informales para nuevas API: UIAccelerometerDelegate es un protocolo formal.

+0

El uso del término "devolución de llamada" es potencialmente confuso aquí, especialmente en un mundo donde existen bloques. De lo que estás hablando es de delegación. (Me doy cuenta de que esta respuesta probablemente tuvo más sentido en 2010.) –

3

Según la respuesta de "Jonathan Sterling", ¿puedo decir que el siguiente código representa un protocolo informal? documentación

de Apple:

"Cuando se utiliza para declarar un protocolo, una interfaz de categoría no tiene una aplicación correspondiente cambio, las clases que implementan el protocolo declaran los métodos de nuevo en sus propios archivos de interfaz y definir a lo largo. con otros métodos en sus archivos de implementación ".

#import <Foundation/Foundation.h> 

@interface Cat1 : NSObject { 


} 
- (void) simpleMethod; 

@end 

@implementation Cat1 

- (void) simpleMethod 
{ 

    NSLog(@"Simple Method"); 
} 

@end 


@interface Cat1 (Cat2) 
- (void) addingMoreMethods; 

@end 




@interface MYClass : Cat1 

@end 

@implementation MYClass 

- (void) addingMoreMethods 
{ 
    NSLog(@"Testing!"); 
} 
@end 

int main (int argc, const char * argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 


    MYClass *myclass = [[MYClass alloc] init]; 
    [myclass addingMoreMethods]; 
    [myclass release]; 
    [pool drain]; 
    return 0; 
} 
+0

Sorta. El método declarado en * Cat2 * es un protocolo informal, más o menos. El uso, sin embargo, no es - típicamente, verías 'if ([myclass respondsToSelector: @selector (addingMoreMethods)]] [myclass addingMoreMethods];'. – bbum

+0

Gracias bbum, no me interesa si se usa demasiado, ¡pero realmente quería entender todo el concepto! – itsaboutcode

+3

El punto, sin embargo, es que un protocolo informal se compone de métodos que pueden implementarse opcionalmente. Por lo tanto, el sitio que llama * debe * verificar para ver si se implementa o de lo contrario la llamada se bloqueará. – bbum

1

un protocolo informal define qué métodos debe comprender un objeto. Esto se llama "conforme a un protocolo". La conformidad con un protocolo es independiente de la jerarquía de clases. Al declarar un puntero para mantener la referencia a un objeto, puede definir a qué protocolos debe ajustarse este objeto. Si escribe código que asigna un objeto que no se ajusta a todos los protocolos requeridos, recibirá una advertencia en tiempo de compilación. Los protocolos informales lo ayudan a confiar en un conjunto de métodos que un objeto comprende. No tiene que invocar isKindOfClass: o responde a: en su código para verificar si los objetos pasados ​​serán adecuados para su procesamiento. Los protocolos son una especie de programación orientada a aspectos.

5

Definimos un informal protocol mediante la agrupación de los métodos en una declaración categoría,

@interface NSObject (MyXMLSupport) 
- initFromXMLRepresentation:(NSXMLElement *)XMLElement; 
- (NSXMLElement *)XMLRepresentation; 
@end 

Informal protocol s se declaran típicamente como categorías de la clase NSObject, Desde que en términos generales asocia los nombres de los métodos con cualquier clase que hereda de NSObject.

Dado que todas las clases heredan de la clase raíz, , los métodos no están restringidos a ninguna parte de la jerarquía de herencia. (También sería posible declarar como informal protocol como una categoría de otra clase para limitarla a una cierta rama de la jerarquía de herencia, , pero hay pocas razones para hacerlo).

Cuando se utiliza para declarar un protocolo, una interfaz de categoría no tiene una implementación correspondiente. En su lugar, las clases que implementan el protocolo declaran los métodos nuevamente en sus propios archivos de interfaz y los definen junto con otros métodos en sus archivos de implementación.

5

protocolos informales son una forma añadir métodos opcionales a un objeto por medio de categoría.

Así que uno puede surgir la duda

¿Se convertirá en el protocolo informal si hay métodos opcionales en el propio protocolo?

La respuesta es no.

Si se declaran los métodos en el protocolo y se dice que se ajusten a una clase sin el uso de categoría entonces es protocolo formal.

Nota:

métodos opcionales en protocolo se introdujeron en c objetivo 2.0 así que antes de que el objetivo se logró a través es decir protocolo informal por medio de categoría.

Categoría:

Es una característica de nivel de idioma pretende ser alternativa para los sub clasificando también conocido como herencia.

espero que arroja algo de luz de la cal en este ..

+1

Gracias por eso '" Nota: "' me dio una imagen completa :-) – byJeevan