Напишите класс Objective-C с нуля - PullRequest
12 голосов
/ 27 мая 2011

Я хотел бы написать класс Objective-C без какао или GNU Object.h (для образовательных целей).Я копался в сети, и мне кажется, что довольно много вещей, которые можно было бы ожидать "прийти с языком", таких как классы и отправка сообщений, на самом деле определены в файлах, написанных третьими лицами, таких как objc-runtime.h.

Существует ли какая-либо документация о том, что такое действительно чистый Objective-C и что является частью среды выполнения / фреймворков?И какую функциональность я должен реализовать, чтобы получить рабочую среду без использования стороннего кода, такого как Object.h или objc-runtime.h (еще раз отметим, что это для образовательных целей, а не для производственного кода)?

Спасибо за понимание!

Ответы [ 4 ]

5 голосов
/ 27 мая 2011

Действительно, единственное, что вы должны позаботиться о себе, если не наследуете от NSObject, - это создание и уничтожение объектов;в противном случае методы ведут себя одинаково независимо от их родительского класса.Такие функции, как KVC и управление памятью, являются функциями OpenStep / Cocoa, но не являются частью языка.

Вот класс с нуля:

@interface MyClass { // note the lack of a superclass here
    @private Class isa;
}
+ (MyClass *)create;
- (void)destroy;

- (int)randomNumber;
@end


@implementation MyClass
+ (MyClass *)create {
    return class_createInstance(self, 0);
}

- (void)destroy {
    object_dispose(self);
}

- (int)randomNumber {
    return rand();
}
@end

И вот как его можно использовать:

int main(int argc, char **argv) {
    MyClass *foo = [MyClass create];
    if (foo) {
        printf("random! %i\n", [foo randomNumber]);
        [foo destroy];
    }
}

Редактировать: Если вы даже не хотите использовать class_createInstance() и object_dispose(), вам придется реализовать эквиваленты вручную, а также эквивалентclass_getInstanceSize() чтобы вы знали, сколько памяти занимает объект.Но даже если вам это удастся, не думайте, что вы избежали выполнения Objective C!Диспетчеризация сообщений все еще полностью построена на функциях C во время выполнения, и синтаксис Objective C преобразуется в вызовы этих функций во время компиляции.

2 голосов
/ 27 мая 2011

Мэтт Галлахер написал действительно классный пост о написании простой программы Какао.Поскольку Objective-C является надмножеством C, вы можете просто сделать:

echo "int main(){return 0;}" | gcc -x objective-c -; ./a.out ; echo $?

В любом случае, вы, вероятно, получите много от чтения его поста.

1 голос
/ 30 декабря 2012

Вот пример класса, без использования class_createInstance или object_dispose, или любого другого времени выполнения Objective C (по крайней мере, мы не вызываем их напрямую).

#import <objc/objc.h>
#import <stdio.h>
#import <stdlib.h>
#import <string.h>

static Class __scratchClass = NULL;

@interface Scratch {
  Class isa;
  char *name;
}
+ (id) initialize;
+ (Scratch*) new:(const char*)strName;
- (void) sayHello;
- (void) destroy;
@end

@implementation Scratch

+ (id) initialize { 
  __scratchClass = self;
  return self;
}

+ (Scratch*) new:(const char*) strName {
  Scratch* pObj = (Scratch*)malloc(sizeof(Scratch));
  if (!pObj) return NULL;
  memset(pObj, 0, sizeof(Scratch));
  pObj->isa = __scratchClass;
  pObj->name = (char*)malloc(strlen(strName)+1);
  strcpy(pObj->name, strName);
  return pObj;
}

- (void) sayHello {
  printf("Hello, World!\nThis is Scratch (%s)...\n", name);
}

- (void) destroy {
  if (name) {
     free(name);
     name = NULL;
  }
  free(self);
}

@end

int main(int argc, char** argv) {
  Scratch* ps = [Scratch new:argv[0]];
  [ps sayHello];
  [ps destroy];
  return 0;
}

Скомпилируйте код ссохранить его как «test1.m»):

gcc -o test1 test1.m -lobjc

1 голос
/ 27 мая 2011

Что касается обхода фреймворка и создания собственного базового объекта, все, что вам нужно сделать, - это убедиться, что первый iVar объявлен Class is_a, и вы, вероятно, сможете получить достаточную поддержку при репликации NSObject, пройдя черезфункции времени выполнения.

Что касается избежания использования библиотеки времени выполнения и структуры, это на самом деле невозможно.Цель C (или, по крайней мере, биты, которые не являются просто C) - это динамический язык.Так что почти все, что он делает, чего не делает C, обрабатывается библиотекой времени выполнения.

Может быть возможно создать свои собственные классы и объекты, используя 32-разрядную среду выполнения и устаревший API, который не абстрагируетсяОтбросьте расположение классов, протоколов и т. д. в той степени, в которой это делает современная среда выполнения (я действительно только возился с современной средой выполнения)

Возможно, вы могли бы создать классы, добавить методы и выделить экземплярыустановка значений в структурах class_t, а затем использование malloc () для выделения, хотя даже в этом случае вы все равно будете неявно использовать функцию времени выполнения objc_msgSend каждый раз, когда используете синтаксис [obj selector] - если только вы не хотите реализовать это вв этом случае вы только что переформулировали язык самостоятельно.«Чистое ядро» языка, который вы ищете - это просто время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...