2014-09-07 2 views
2

Скажем, у меня есть неинициализированный переменную:Получить ссылку на объект класса из неинициализированной переменной - не экземпляр объекта

UIViewController *vc; 

С этой переменной, я хочу, чтобы ссылаться на UIViewController, так что я мог бы назвать alloc или new на чтобы вернуть экземпляр объекта.

По существу, я хочу сделать:

UIViewController *vc = [*typeof(vc) new]; 

... который не компилируется, поскольку компилятор ожидает выражение, а не тип.

Если @encode вернулся фактический тип, я мог бы сделать что-то вроде:

UIViewController *vc = [NSClassFromString(@(@encode(*typeof(vc)))) new]; 

... однако, @encode возвращает '@', который просто означает "общий объект".

Я понимаю, что это немного философский характер, но я устал печатать и хотел бы сделать макрос, как NEW(x). Я также понимаю, что аналогичный макрос можно сделать, если он включает в себя фактическое объявление, но я не удовлетворен этим синтаксисом/углом.

+0

'#define NEW (класс, varname) class * varname = [class new]' неудовлетворительно, вы говорите? –

+0

Да. Я придумал что-то (см. Мой ответ), но это не удивительно. Я, вероятно, не сделаю этого. – xtravar

+0

Аналогичная проблема, но не идентична, потому что у вас все еще есть доступ к локальному объявлению: [ObjC вы можете проверить неинициализированный указатель на статический тип класса?] (Http://stackoverflow.com/q/7680310) Это объясняет, почему это не " t вообще возможно, однако. –

ответ

0

Вот что у меня ... это не кажется идеальным, так как это приводит к удару по производительности. Все еще ищут лучшие ответы.

static Class classFromEncoding(const char *encoding) { 
    char *className = strndup(encoding + 1, strchr(encoding, '=') - encoding - 1); 
    Class retval = NSClassFromString(@(className)); 
    free(className); 
    return retval; 
} 

#define NEW(variable) [classFromEncoding(@encode(typeof(*variable))) new] 

Вот макро-единственная версия:

#define CLASS_FROM_VARIABLE(variable) \ 
^(const char *encoding) {    \ 
char *className = strndup(encoding + 1, strchr(encoding, '=') - encoding - 1); \ 
Class retval = NSClassFromString(@(className));  \ 
free(className);       \ 
return retval;        \ 
}(@encode(typeof(*variable))) 

#define NEW(variable) [CLASS_FROM_VARIABLE(variable) new] 
#define ALLOC(variable) [CLASS_FROM_VARIABLE(variable) alloc] 

Вариации могут быть выполнены с использованием objc_getClass() или NSString initWithBytes, возможно, с приростом производительности. Тем не менее, это не «не-op», а именно то, что я бы предпочел.

+0

Я бы предположил, что каждый, кто читает ваш код с помощью этого макроса, собирается поставить шестерку на ваш песчанок. –

+0

Я бы определенно ограничил свое использование. :) Я люблю Objective-C, но инициализаторы являются самой раздражающей частью моего дня (именно поэтому я переехал в новый лагерь вместо alloc] init]). – xtravar

+0

Мне жаль, кто наследует вашу базу кода. – CrimsonChris

-1

Это [obj class] или [obj className] в зависимости от ваших потребностей.

+0

Объект не был инициализирован; нет ничего, чтобы реагировать на эти сообщения. –

+0

Правда, мой плохой. NSClassFromString() кажется лучшим способом, чем. – Gobra

Смежные вопросы