2010-08-11 12 views
13

Cuando estaba leyendo acerca de la nueva actualización de iOS 4.0.2, quería saber qué hacen o intentar hacer los hackers con un desbordamiento de búfer, que después de algunas wikipedia me interesó jugar con malloc y crear así mi propio "NSObject".reimplementando NSObject desde cero

No estoy planeando usar esto en ninguna de mis aplicaciones, es solo para aprender y jugar con Objective-c.

Y por supuesto, como era de esperar encontré algunos problemas que no pude resolver por mi cuenta.

para la creación de mi objetivo que hago:

+ (id)create{ return malloc(sizeof(self)); } 

y

- (void)free { free(self); } 

Al llamar [TestObject Crear]; Recibo los siguientes mensajes de consola:

"11/11/10 11:17:31 PM TestingHeap [2675] *** NSInvocación: advertencia: el objeto 0x100002100 de la clase 'AObject' no implementa doesNotRecognizeSelector: - abortar"

¿Entonces está tratando de manejar mi objeto como un objeto NSO ...? y como soluciono esto

Además, al compilar sin Foundation o AppKit, aparece un error al perder símbolos, __objc_empty_vtable y __objc_empty_cache en particular. He intentado incluir varios archivos de cabecera de/usr/include/objc/

Gracias de antemano.

actualización

Después de enlazar con la librería libobjc recibo EXC_BAD_INSTRUCTION cuando se trata de llamar a un método de mi clase.

+0

Es posible que desee echar un vistazo al Protocolo NSObject, si no lo ha hecho: http://developer.apple. com/mac/library/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html – Justin

+0

La inclusión de archivos de encabezado no resolverá los errores de símbolos faltantes, que provienen del enlazador. Debes enlazar con libobjc (normalmente hecho por ti por Foundation). –

+3

Probablemente no desee obtener el tamaño usando 'sizeof (self)' de todos modos. 'self' es un puntero, por lo que obtendrá el tamaño del puntero. Puede usar 'class_getInstanceSize' en su lugar. – David

Respuesta

9

Necesita usar class_getInstanceSize en lugar de sizeof, como señaló David.

Debes establecer un vínculo con libobjc (como descubriste a ti mismo).

Su clase base requiere un puntero isa que se debe establecer en su método create.

Y el tiempo de ejecución requiere la implementación de un método +initialize que se invocará antes de que se use la clase la primera vez. Si falta, se bloquea.

Así que todas las cosas de su clase base debe tener al menos esto:

#include <objc/objc.h> 
#include <objc/runtime.h> 
#include <stdlib.h> 

@interface MyBase { 
    Class isa; 
} 

+ (id) alloc; 
- (void) free; 

@end 

@implementation MyBase 

+ (void) initialize; 
{ 
} 

+ (id) alloc; 
{ 
     size_t size = class_getInstanceSize(self); 
     MyBase *result = malloc(size ); 
     result->isa = self; 
     return result; 
} 

- (void) free; 
{ 
     free(self); 
} 

@end