Цель C - Объявление / определение функции между предварительно скомпилированным условием - PullRequest
0 голосов
/ 30 сентября 2019

Есть ли способ написать функцию между предварительно скомпилированным условием, чтобы функция была доступна только в том случае, если это условие истинно? Кроме того, я могу использовать переменную экземпляра там? Вот так -

#if ([self.object ifVariablenotNil])
- (UIModalPresentationStyle)modalPresentationStyle{
    return UIModalPresentationFullScreen;
}
#endif

Ответы [ 2 ]

2 голосов
/ 30 сентября 2019

Краткий ответ:

Да, но вам нужно, если в курс необходимо включить условие: #if condition-expression

Более длинный ответ:

Мы предполагаем, что проблема здесь может заключаться в понимании того, что может быть условным выражением , если мы ошибаемся, игнорировать остальные!

Директивы, такие как #if являются частью препроцессора (Objective-) C , они имеют свои собственные правила синтаксиса, совершенно независимые от (Objective-) C. Вся предварительная обработка (по крайней мере, логически) выполняется до того, как код (Objective-) C будет проанализирован и скомпилирован.

Это означает, что препроцессор выражение не может использовать (Objective-) константы Cпеременные, функции или операторы;он может использовать только символы и операторы препроцессора.

Аналогично, анализ и компиляция кода (Objective-) C не имеют доступа к символам препроцессора per se , поскольку все они были заменены предыдущими текстовыми. фаза препроцессора.

Короче говоря: существует два разных мира: препроцессор и язык (Objective-) C, и они не взаимодействуют напрямую.

Выражения препроцессора, как указывается в документации,это, «подлежит строгим ограничениям» ;они работают только с целочисленными и строковыми константами, а также с несколькими операторами, которые отражают их (Objective-) C-аналоги.

Вот реальный пример, взятый из SVGKit:

#if SVGKIT_UIKIT && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_7_0
void CGPathAddRoundedRect (CGMutablePathRef path, CGRect rect, CGFloat radiusX, CGFloat radiusY);
#endif

Здесь SVGKIT_UIKIT, __IPHONE_OS_VERSION_MAX_ALLOWED и __IPHONE_7_0 - все символы препроцессора, которые либо были бы #define 'd в другом месте кода, заданные значения, использующие переключатель командной строки компилятора, поступают из настроек проекта Xcode, определяются самим компилятором,и т.д ..

Чтобы оценить это выражение, препроцессор сначала заменяет символы текстовым определением (все символы препроцессора имеют текстовые значения). При компиляции для UIKit вышеприведенное может быть сначала преобразовано в:

#if 1 && 60100 < 70000

, где 1 - это определение SVGKIT_UIKIT, 70000 - это определение __IPHONE_7_0, а 60100 - этоопределение __IPHONE_6_1 и было выбрано в качестве определения __IPHONE_OS_VERSION_MAX_ALLOWED.

Заменив все символы, препроцессор оценивает выражение, используя семантику, аналогичную (Objective-) C, поэтому одиночный ненулевой 1 оценивается как true, 60100 < 70000 оценивается до true, а затем true && true оценивается до true, и условие if выполняется, поэтому следующий текст (препроцессор невсе равно, если его (Objective-) C или стихотворение Робби Бернса) до #endif включено в текст, переданный на следующую фазу компилятора.

HTH

1 голос
/ 01 октября 2019

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

Итак, чтобы ответить на ваш вопрос: Нет, это невозможно.

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