Переоснащение NSObject с нуля
Когда я читал о новом обновлении iOS 4.0.2, я хотел знать, что делают хакеры или пытаются делать с переполнением буфера, который после некоторого wikipedia'ин меня заинтересовал в игре с malloc и тем самым создал свой собственный "NSObject" ".
На самом деле я не планирую использовать это в любом из моих приложений, это только для обучения и игры с помощью objective-c.
И, конечно же, как и ожидалось, я столкнулся с некоторыми проблемами, которые я не мог решить самостоятельно.
для создания моего объекта я делаю:
+ (id)create{ return malloc(sizeof(self)); }
и
- (void)free { free(self); }
При вызове [TestObject create]; Я получаю следующие сообщения консоли:
"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/
Спасибо заранее.
Обновление
После связывания с libobjc я получаю EXC_BAD_INSTRUCTION при попытке вызвать метод из моего класса.
Ответы
Ответ 1
Вам нужно использовать 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