Построение динамических классов в Objective C - PullRequest
4 голосов
/ 15 марта 2010

Я довольно компетентный программист на рубине. Вчера я решил наконец попробовать свои силы с платформами Apple Cocoa. Помогите мне увидеть вещи с точки зрения ObjC?

Я пытаюсь разобраться с objc_allocateClassPair и objc_registerClassPair. Моя цель состоит в том, чтобы динамически генерировать несколько классов и затем использовать их, как любой другой класс. Это работает в Obj C?

Распределив и зарегистрировав класс A, я получаю ошибку компиляции при вызове [[A alloc] init]; (там написано 'A' Undeclared). Я могу только создать экземпляр A, используя метод objc_getClass времени выполнения. Есть ли способ сообщить компилятору о A и передать ему сообщения, как я бы NSString? Флаг компилятора или что-то?

У меня есть 10 или около того других классов (B, C, ...), все с тем же суперклассом. Я хочу отправить их напрямую в коде ([A classMethod], [B classMethod],…) без необходимости objc_getClass. Я пытаюсь быть здесь слишком динамичным или просто не справляюсь со своей реализацией? Это выглядит примерно так ...

 NSString *name = @"test";  
 Class newClass = objc_allocateClassPair([NSString class], [name UTF8String], 0);  
 objc_registerClassPair(newClass);  

 id a = [[objc_getClass("A") alloc] init];  
 NSLog(@"new class: %@ superclass: %@", a, [a superclass]);  
 //[[A alloc] init]; blows up.

Ответы [ 4 ]

5 голосов
/ 15 марта 2010

Причина взрыва [[A alloc] init]; в том, что компилятор понятия не имеет, что означает A. Компилятор никогда не знает, что A даже там.

Редактировать: Кроме того, похоже, что вы хотите:

@interface A : NSObject {
  NSString *myString;
}

- (id)initWithString:(NSString *)string;

- (void)doItToIt;

@end

или, возможно,

@interface NSString (MyPrivateExtension)

- (void)doItToIt;

@end
1 голос
/ 21 ноября 2013

Посмотрите на http://www.mikeash.com/pyblog/friday-qa-2010-11-6-creating-classes-at-runtime-in-objective-c.html и https://github.com/mikeash/MAObjCRuntime

Он описывает только то, чего вы пытаетесь достичь, и обеспечивает хорошую абстракцию по сравнению с необработанными вызовами времени выполнения Objective C.

1 голос
/ 28 мая 2010

Когда вы определяете класс на языке Objective-C, компилятор определяет новый тип. Когда вы создаете класс динамически, компилятор не знает этого типа, поэтому ваш единственный выбор - использовать класс в качестве идентификатора и динамически отправлять ему сообщения. Ruby - это динамически типизированный язык, который, вероятно, использует те же механизмы, что и компилятор при определении классов во время выполнения.

0 голосов
/ 28 мая 2010

Взгляните на невероятные F-Script и FSClass , которые могут сделать это и имеют открытый исходный код. FSClass определяет метакласс, который можно разделить на подклассы во время выполнения.

Это работает с использованием objc_allocateClassPair и objc_registerClassPair , но есть много других вещей (помимо меня!), Которые, вероятно, помогут.

...