2010-07-27 9 views
10

Estoy cambiando la clase de algunos objetos usando object_setClass(id object, Class cls). Estoy cambiando la clase a una subclase de la clase original. Luego establezco algunas propiedades que solo están definidas en la subclase, y las cosas parecen funcionar bien.object_setClass a clase más grande

Estaba un poco sorprendido de que esto funcionara, porque object_setClass, por lo que yo entiendo, no reasigna el objeto, solo cambia el puntero isa. Si las instancias de la subclase son considerablemente más grandes (es decir, tienen muchos más ivars) que las instancias de la clase original, no veo cómo el objeto puede funcionar como se esperaba.

Funciona solo porque hay mucha memoria intermedia entre los objetos en la memoria (debido a la alineación, etc.)?

¿Es esto robusto o podría fallar bajo ciertas circunstancias?

Respuesta

6

Podría fallar. Como se puede ver en el código fuente del tiempo de ejecución here, realmente solo cambia el puntero isa.

Si realmente desea intercambiar la isa a un isa de una subclase con más Ivars, se debe utilizar con class_createInstance distinto de cero extraBytes.

+0

gracias, eso es lo que tenía miedo y tiene sentido, por supuesto. No veo cómo su solución podría ayudar, porque no quiero crear un nuevo objeto. (No puedo, porque el objeto es una propiedad de solo lectura de otra clase). – Felixyz

+0

Si es su código, puede organizar la propiedad que se creará con los bytes adicionales para que pueda cambiar la clase de forma segura más adelante. ¡Pero no creo que sea una buena idea cambiar la clase de una propiedad de solo lectura! ¿Por qué estás haciendo eso? – Yuji

+0

Pensé que era un pequeño truco inteligente para modificar una vista cargada desde una punta. Pero recurriré a más métodos estándar. – Felixyz

3

En lugar de utilizar una subclase más grande, use objc_setAssociatedObject y objc_getAssociatedObject para adjuntar objetos dinámicamente adicionales a su objeto existente de tamaño fijo.

Cuestiones relacionadas