2012-04-09 14 views
18

¿Hay alguna manera de indicar al compilador que un objeto de clase cumple con un protocolo?¿Puede un objeto de clase ObjC ajustarse a un protocolo?

Según entiendo, mediante la creación de +(void)foo métodos de clase, una instancia de esa clase de objeto tendrá esos métodos como métodos de instancia. Por lo tanto, siempre que creara métodos +(void)foo para todos los métodos de protocolo requeridos, puedo hacer que un objeto de clase actúe como delegado.

Mi problema, por supuesto, es que en el archivo de encabezado de la clase, solo sé cómo indicar que las instancias de la clase se ajustan al protocolo (como suele ser el caso). Por lo tanto, la mejor que he descubierto es convertir el objeto de clase de este modo:

something.delegate = (id<SomethingDelegate>)[self class] 

¿Alguna idea?

relacionada, pero diferente: ObjC: is there such a thing as a "class protocol"?

Respuesta

17

Lo que está haciendo ahora es correcto, ya que silenciará las advertencias, que es su objetivo. Estará enviando los mensajes de objeto de clase definidos en el protocolo para instancias que son un poco confusas, pero al tiempo de ejecución no le importa.

Piénselo de esta manera: desea establecer un delegado en un objeto que responda a los mensajes definidos en el protocolo. Tu clase hace esto, y tu clase también es un objeto. Por lo tanto, debe tratar a su clase como un objeto que se ajuste a ese protocolo. Por lo tanto, lo que has escrito es completamente correcto (en función de lo que intentas hacer).

Una cosa a tener en cuenta, sin embargo, es que esta clase no responderá correctamente a conformsToProtocol:. En general, esto está bien para la configuración de un delegado (los delegados generalmente no verifican si la clase cumple con —, solo comprueban si puede responder a un selector).

Como nota al margen, una cosa que puede hacer es sintácticamente:

Class<SomethingDelegate> variable = (Class<SomethingDelegate>)[self class]; 

La diferencia aquí es que el compilador utilizará los métodos de la clase del protocolo en lugar de mensajes de instancia. Sin embargo, esto no es lo que quieres en tu caso.

+1

Aún necesita la sintaxis del puntero. 'Clase *'. –

+4

No necesita la sintaxis del puntero. 'Class' ya es un puntero (se define como' typedef struct objc_class * Class'. Solo lo necesitarías si necesitas un puntero a una clase (que probablemente sea bastante raro). – wbyoung

+0

Nono, quiero decir 'Class' como en marcador de posición, no 'Clase 'como en el tipo real. Creo que leí mal su publicación. –

7

No hay sintaxis de Objective-C para indicar que una metaclase es conforme a un protocolo.

Creo que puede hacerlo en tiempo de ejecución, usando class_addProtocol en la metaclase. Pero no lo he intentado.

Supongo que también podría escribir un método +conformsToProtocol: en su clase y mentir sobre su conformidad. Esto podría tener efectos secundarios inesperados, ya que ya hay un +conformsToProtocol: en NSObject (además de -conformsToProtocol:).

Ninguno de estos eliminará la necesidad de un molde para cerrar el compilador. Solo usa un singleton.

Cuestiones relacionadas