Переоснащение 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