Crear una clase en tiempo de ejecución: ¿por qué NSClassFromString AND objc_getclass devuelve nil?

StackOverflow https://stackoverflow.com/questions/1634644

  •  06-07-2019
  •  | 
  •  

Pregunta

He intentado usar ambos:

NSClassFromString and objc_getclass 

para devolver una clase, de modo que pueda crearla en tiempo de ejecución, pero ambas funciones devuelven nil para algunas clases, por ejemplo "TestClass". Tenga en cuenta que NSClassFromString funciona para mí para el 99% de las clases.

Si agrego

[TestClass class];

antes de llamar a NSStringFromClass u objc_getclass, funciona. y si trato de crear la clase usando una referencia de clase, es decir:

[TestClass alloc];

también funciona. Entonces, ¿cómo puedo forzar la carga de la clase en tiempo de ejecución para que NSClassFromString u objc_getclass no devuelvan nil?

¿Fue útil?

Solución

Me encontré con este mismo problema. En mi caso, tenía un código que buscaba la clase usando

Class aClass = objc_getClass("Foo");

Que funcionó cuando la clase Foo estaba en el mismo paquete de proyectos que mi AppDelegate.

Como parte de la refactorización del código, moví la clase Foo y las clases de modelo asociadas fuera del proyecto AppDelegate a un proyecto común de lib estática que sería más fácil de probar y reutilizar.

Cuando moví la clase Foo a libFooBar, la objc_getClass (" Foo ") ahora devolvió nil en lugar de la clase Foo.

Para resolver esto, llamé a la clase que me interesa para que las clases de libFooBar se registren con el tiempo de ejecución de Objective-C. Hice esto así:

Foo* foo = [[Foo alloc] init];
[foo release];
Class aClass = objc_getClass("Foo");

Ahora objc_getClass (" Foo ") devuelve la clase Foo nuevamente en lugar de nula.

Solo puedo suponer que las clases de la biblioteca estática no se registran hasta que se realiza una llamada a una de las clases en la biblioteca estática.

Otros consejos

La referencia de tiempo de ejecución de Objective-C puede ayudarlo aquí. Por ejemplo, la documentación de objc_getClass dice: "El objeto de clase para la clase nombrada, o nulo si la clase no está registrada con el tiempo de ejecución de Objective-C". Si busca una discusión sobre el registro, encontrará este dato en objc_getClassList:

  

" La biblioteca de tiempo de ejecución Objective-C registra automáticamente todas las clases definidas en su código fuente. Puede crear definiciones de clase en tiempo de ejecución y registrarlas con la función objc_addClass. & Quot;

(Y, por supuesto, los documentos están desactualizados porque objc_addClass está en desuso, objc_allocateClassPair y objc_registerClassPair en su lugar).

Esto parece un mundo de dolor si no te lo pones fácil. ¿Hay alguna posibilidad de que pueda hacer referencia a sus clases dinámicas en el código cuando se inicia la aplicación?

Tuve que agregar manualmente la clase (por ejemplo, TestClass.m) a la configuración de compilación. Fases de construcción > Recopilar fuentes > + > TestClass.m

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top