2010-08-11 6 views
13

Когда я читал о новом обновлении iOS 4.0.2, я хотел знать, что делают хакеры или пытаются сделать с переполнением буфера, которые после некоторого wikipedia'ин меня заинтересовали игрой с malloc и тем самым созданием мой собственный «NSObject».reimplementing NSObject с нуля

Я на самом деле не планирую использовать это в любом из моих приложений, это только для обучения и игры с объективом-c.

И, конечно же, как и ожидалось, я столкнулся с некоторыми проблемами, которые я не мог решить сам.

для создания моего объекта я:

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

и

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

При вызове [TestObject создать]; Я получаю следующие сообщения консоли:

«8/11/10 11:17:31 PM TestingHeap [2675] *** NSInvocation: warning: object 0x100002100 класса« AObject »не реализует doesNotRecognizeSelector: - abort"

Значит, он пытается обрабатывать мой объект как NSObject ..? и как я могу это решить.

Также при компиляции без Foundation или AppKit я получаю сообщение об ошибке для отсутствующих символов: __objc_empty_vtable и __objc_empty_cache в частности. Я попытался включить несколько файлов заголовков из/usr/include/objc/

Заранее спасибо.

Update

После связывания с libobjc я получаю EXC_BAD_INSTRUCTION при попытке вызова метода из моего класса.

+0

Вы можете взглянуть на Протокол NSObject, если вы еще не: http://developer.apple. com/mac/library/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html – Justin

+0

Включение файлов заголовков не приведет к устранению ошибок недостающих символов, которые исходят от компоновщика. Вам нужно связать с libobjc (обычно сделанным для вас Foundation). –

+3

Вы, вероятно, не хотите получать размер с помощью 'sizeof (self)' в любом случае. 'self' - это указатель, и вы просто получите размер указателя. Вместо этого вы можете использовать 'class_getInstanceSize'. – David

ответ

9

Вам необходимо использовать class_getInstanceSize вместо sizeof, как указал Дэвид.

Вам необходимо установить ссылку на libobjc (как вы выяснили сами).

Ваш базовый класс требует указателя isa, который должен быть установлен в вашем методе create.

И для выполнения требуется метод +initialize, который будет вызываться до того, как ваш класс будет использоваться в первый раз. Если он отсутствует, он сработает.

Так все вместе ваш базовый класс должен иметь по крайней мере, это:

#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 
Смежные вопросы