objective-c introspection

objective c - Acceso a un método en una súper clase cuando no está expuesto



objective-c introspection (3)

En una subclase, estoy anulando un método que no está expuesto en la súper clase. Sé que tengo la firma correcta, ya que está anulando con éxito la implementación de la superclase. Sin embargo, como parte de la nueva implementación, debo llamar a la implementación de la superclase desde la implementación de la subclase.

Debido a que no está expuesto, tengo que invocar el método mediante una llamada a performSelector :

SEL superClassSelector = NSSelectorFromString(@"methodToInvoke"); [super performSelector:superClassSelector];

Sin embargo, en mi aplicación, esto da como resultado un bucle recursivo infinito en el que se invoca la implementación de la subclase cada vez que trato de invocar la implementación de la superclase.

¿Alguna idea?

Me doy cuenta de que esta es una situación atípica, pero desafortunadamente no hay manera de evitar lo que estoy tratando de hacer.


Esto no funciona porque solo está enviando performSelector: no el selector que le pasa a eso, a la superclase. performSelector: todavía busca el método en la lista de métodos de la clase actual. Así, terminas con la misma implementación de subclase.

La forma más sencilla de hacer esto puede ser simplemente escribir su propia llamada a objc_msgSendSuper() :

// Top level (this struct isn''t exposed in the runtime header for some reason) struct objc_super { id __unsafe_unretained reciever; Class __unsafe_unretained superklass; }; // In the subclass''s method struct objc_super sup = {self, [self superclass]}; objc_msgSendSuper(&sup, _cmd, other, args, go, here);

Esto puede causar problemas en el caso general, como ha señalado Rob Napier a continuación. Sugerí esto basado en el supuesto de que el método no tiene valor de retorno.


La forma en que he manejado esto es volver a declarar la interfaz de su súper clase en el archivo de implementación de la subclase con el método al que desea llamar desde la subclase

@interface MySuperclass() - (void)superMethodIWantToCall; @end @implementation MySubclass - (void)whateverFunction { //now call super method here [super superMethodIWantToCall]; } @end

No estoy seguro de si esta es la mejor manera de hacer las cosas, ¡pero es simple y funciona para mí!


Una forma de hacerlo es crear una categoría de su clase en un archivo separado con el método que está intentando exponer.

@interface MyClass (ProtectedMethods) - (void)myMethod; @end

y en la .m

@implementation MyClass (ProtectedMethods) - (void)myMethod { } @end

Luego, importa esta categoría desde tus archivos .m y listo. No es lo más bonito, pero hará el truco.