переоснащение NSObject с нуля - PullRequest
13 голосов
/ 12 августа 2010

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

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

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

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

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

и

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

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

"11.08.10 11:17:31 TestingHeap [2675] *** NSInvocation: предупреждение: объект 0x100002100 класса 'AObject' не реализует hasNotRecognizeSelector: -abort "

Итак, он пытается обработать мой объект как объект NSObject ..?и как мне это решить.

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

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

Обновление

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

1 Ответ

9 голосов
/ 26 августа 2010

Вам нужно использовать 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
...