2011-10-01 14 views
15

Tengo una pregunta de tarea que me confundió, realmente mal. A continuación hay una breve explicación de una pregunta.Uso de protocolos de Objective C

Imagine que está desarrollando una aplicación que almacena información de contacto . La libreta de direcciones puede contener muchos tipos de entidades, por ej. Human siendo, una empresa o cualquier otra cosa que tenga una información de contacto.

  • Ahora en vez de comprobar de forma explícita cada tipo de objeto escribir un protocolo que declara cómo debe comportarse un objeto y con éxito aparecer en su libreta de direcciones.

Mi comprensión y el esfuerzo de responder a esta pregunta es,

  1. Construir un protocolo que tiene métodos comunes de cada tipo de información de contacto bajo @required etiqueta. Y todos los demás métodos que no son similares en contacto diferente (como el número de fax tiene asociación con la empresa pero no con la persona ...) en @optional. En tiempo de ejecución, puede verificar si un objeto responde a cualquier método dado usando selector. Duda: Sin embargo, esto de nuevo está comprobando explícitamente el tipo de objeto indirectamente, ¿estoy en lo cierto?

  2. Mi segunda idea es usar algo como abstract class en java. Lo que significa que las clases heredadas de la clase abstracta implementan sus propios métodos abstractos. ¿Sin embargo, como desarrollador ingenuo de iOS, no sé cómo implementar esto? y no estoy seguro de si esto va a resolver mi problema. Me gustaría que me iluminen si alguien sabe esto.


lectura externa realizada hasta ahora, por favor, hágamelo saber si la respuesta Busco está en uno de estos enlaces. Lo leeré nuevamente para entender y resolver esto :). Gracias.

  1. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF144

  2. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF146

  3. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF149

+5

Excelente forma de hacer la tarea pregunta. +1 para seguir http://catb.org/esr/faqs/smart-questions.html – 0x8badf00d

+0

Este enlace explica claramente los conceptos de protocolo http://www.tutorialspoint.com/ios/ios_delegates.htm –

Respuesta

10

Un protocolo es el mismo que una interfaz Java. Simplemente define qué métodos debe soportar la clase. Aquí hay una página que explica claramente: http://www.otierney.net/objective-c.html#protocols

Esencialmente si desea asegurarse de que una clase tendrá un método phoneNumber (descriptor de acceso a la propiedad phoneNumber) que haría algo como esto:

@protocol ContactProtocol 
-(void) phoneNumber; 
@end 

@interface Person: NSObject <ContactProtocol> { 
    ... 
} 

@interface Company: NSObject <ContactProtocol> { 
    ... 
} 

Y luego en tiempo de compilación (o en vivo para xcode 4) le dirá si olvidó agregar el método phoneNumber a las clases Person o Company.

+6

Los protocolos no son lo mismo que clases abstractas; en cambio, son análogos a las interfaces en Java. Cuando deriva una clase de una clase abstracta, hereda los métodos y sus implementaciones. Con una interfaz, obtienes solo las declaraciones. Lo mismo es cierto con los protocolos Obj-c: cuando declaras que una clase implementa un protocolo, debes proporcionar las implementaciones del método. – Caleb

+0

Tienes toda la razón. ¡Estaba pensando en interfaces! Estoy actualizando mi respuesta. –

+0

El enlace a Otierney.net está actualmente fuera de servicio. Aquí hay un enlace a la memoria caché de Google, no estoy seguro de cuánto funcionará.http://webcache.googleusercontent.com/search?q=cache:QbGm74kZa1wJ:www.otierney.net/objective-c.html+&cd=1&hl=en&ct=clnk&gl=us – kevins

4

Sin embargo, esto de nuevo está comprobando explícitamente el tipo de objeto indirectamente, ¿estoy en lo cierto?

No, el comportamiento de comprobación es diferente del tipo de comprobación. Puede enviar -respondsToSelector: a cualquier objeto, y si el resultado es SÍ, puede enviar el mensaje independientemente del tipo de objeto. También puede requerir que un objeto implementar un protocolo dado, de nuevo sin importar su tipo real:

id<SomeProtocol> foo; // foo points to any type that implements SomeProtocol 

Mi segundo pensamiento es usar algo como clase abstracta en Java.

Eso podría funcionar, pero aparentemente no es lo que pidió su tarea, ¿verdad? Se dice "... escribir un protocolo ..."

Objective-C no proporciona una manera de hacer explícita una clase abstracta de la manera que lo hace Java. Simplemente crea la clase, y si no quiere que se cree una instancia directamente, documente eso en alguna parte.

+0

Esta pregunta no era sobre Swift, pero si fue entonces, por favor corrígeme si me equivoco: su primera respuesta sería: sí, ahora en Swift, el protocolo es un tipo y simplemente 'delegate? .someMethod' mientras que no es idéntico a' respondsToSelector' se ejecutará la función si se establece un delegado ... 2da pregunta: (después de leer su comentario para la respuesta aceptada) en Swift ya que también puede proporcionar implementaciones predeterminadas a protocolos de forma muy similar a la clase abstracta. – Honey

+1

@Honey Esta respuesta es anterior a Swift, y debe leerse en ese contexto. Lo mismo ocurre con mi comentario. E incluso si la pregunta y las respuestas fueron contemporáneas con Swift, el título de la pregunta * claramente * dice "Objective-C" y la pregunta está etiquetada [tag: objective-c]. – Caleb

+0

De verdad lo sé, solo estaba preguntando sobre su diferencia con Swift. Hay respuestas en este tema y solo estaba verificando si podía juntar todo (especialmente junto con su comentario anterior) correctamente. – Honey

1

Tiene ... opciones.

métodos opcionales son convenientes para la persona que escribe la clase para cumplir con el protocolo, molesto para la persona que hace uso del protocolo. Entonces depende de a quién intentes complacer.

Los métodos opcionales no son tan malos como el tipo de comprobación. Imagine cómo se vería el código al acceder a un objeto de entidad contactable. Cuando usa un método opcional, debe tener un caso if y un caso else. No es tan conveniente como seguir adelante y asumir que puedes llamar al método. Pero es mucho más conveniente que consultar el tipo. Eso sería uno si fuera el caso para cada tipo diferente de entidad (y un caso else, que podría ser una aserción). Además, si usa métodos opcionales, la información sobre la entidad se encapsula en su clase. Si marca el tipo antes de llamar a un método, la información sobre qué tipo de información de contacto proporciona una entidad está fuera de la clase en el código de llamada. Si actualiza la entidad para proporcionar un tipo adicional de contacto, esa mejora no estará disponible hasta que actualice el código de llamada.

Opción B es hacer que todos los métodos necesarios, sino darles la opción de devolver un valor que indica que no hay información disponible, tales como nula. Por supuesto, eso todavía significa un caso para verificar si hay un resultado nulo, es menos detallado. Una solución aún mejor para este problema es hacer que los métodos devuelvan colecciones de contactos múltiples. Después de todo, las personas pueden tener más de un número de teléfono. Luego, para indicar que un tipo de contacto no es aplicable, simplemente devolverá una colección vacía.

El inconveniente es que quien escribe la clase que cumple con el protocolo tiene que agregar un método stub simple que dice return nil o algo así.

Cuestiones relacionadas