tutorial objective español caracteristicas objective-c runtime uitableview protected

objective c - español - Objective-C: ¿Cómo cambiar la clase de un objeto en tiempo de ejecución?



tutorial xcode 9 español (2)

Traté de responder utilizando una subclase UITableView con un UITableViewController con ISA Switching así:

self.tableView->isa = [MyTableView class];

Pero obtengo el error de compilación: la Instance variable ''isa'' is protected.

¿Hay alguna forma de evitar esto? Y, si es así, ¿es seguro hacerlo?

Lo pregunto porque la respuesta de @AmberStar a esa pregunta parece un poco defectuosa. (Ver mi comentario)


La forma segura es crear una nueva instancia.

Intercambiar isa no es seguro: no tiene idea de cuál es el diseño de la memoria de una clase o lo que será en el futuro. Incluso avanzar en el gráfico de herencia realmente no es seguro porque la inicialización y destrucción de los objetos no se realizarían correctamente, dejando su objeto en un estado potencialmente no válido (lo que podría hacer que todo el programa caiga).


Si su clase de vista de tabla proporciona CUALQUIER almacenamiento, esto se romperá. No recomendaría el camino por el que vas a bajar. Pero el método correcto sería usar object_setClass(tableView, [MyTableView class]) .

Por favor, asegúrese de que esto sea realmente lo que quiere.

Aquí hay una pequeña muestra de código que muestra cómo esta es una idea horrible.

#import <objc/runtime.h> @interface BaseClass : NSObject { int a; int b; } @end @implementation BaseClass @end @interface PlainSubclass : BaseClass @end @implementation PlainSubclass @end @interface StorageSubclass : BaseClass { @public int c; } @end @implementation StorageSubclass @end int main(int argc, char *argv[]) { BaseClass *base = [[BaseClass alloc] init]; int * random = (int*)malloc(sizeof(int)); NSLog(@"%@", base); object_setClass(base, [PlainSubclass class]); NSLog(@"%@", base); object_setClass(base, [StorageSubclass class]); NSLog(@"%@", base); StorageSubclass *storage = (id)base; storage->c = 0xDEADBEEF; NSLog(@"%X == %X", storage->c, *random); }

y la salida

2011-12-14 16:52:54.886 Test[55081:707] <BaseClass: 0x100114140> 2011-12-14 16:52:54.889 Test[55081:707] <PlainSubclass: 0x100114140> 2011-12-14 16:52:54.890 Test[55081:707] <StorageSubclass: 0x100114140> 2011-12-14 16:52:54.890 Test[55081:707] DEADBEEF == DEADBEEF

Como puede ver, la escritura en storage->c escribió fuera de la memoria asignada para la instancia y en el bloque que asigné para el azar. Si ese fuera otro objeto, acaba de destruir su isa puntero.