Локальное объявление указателей только для iOS 6 (например, NSLayoutConstraint)

У меня есть приложение, которое поддерживает как iOS 5, так и iOS 6. В одном классе мне нужно объявить локально некоторые указатели NSLayoutConstraint, которые доступны только для iOS 6. Я использую их только для макета iOS 6, потому что для iOS 5 я автоматически изменяю размер макета. Этот класс используется как для iOS 5, так и для iOS 6.

Есть ли способ объявить некоторые указатели NSLayoutConstraint в заголовочном файле класса, чтобы я не получил исключение в iOS 5?

Я пробовал следующее, но я получаю ошибку компилятора в моем файле реализации, что это ограничение не объявлено:

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0
NSLayoutConstraint *exampleConstraint;
#endif

Большое спасибо за любые предложения

Линард


person Linard Arquint    schedule 27.05.2013    source источник
comment
Кроме того, я удивлен, что вы вообще используете авторазметку (даже если только для приложения iOS6), если вы поддерживаете iOS5. Почему бы просто не отключить авторазметку вообще? Это не требуется в iOS6. Если у вас правильно работает макет в iOS5 с использованием масок авторазмера, то почему бы вам не использовать это, когда приложение работает на iOS 6? Если у вас есть приложение, работающее на iOS 5 без автоматического макета, то зачем дублировать ваши усилия, также имея представление автомакета, специфичное для iOS6? Код без автомакета должен нормально работать на iOS6, и мне кажется, что вы излишне дублируете свои усилия.   -  person Rob    schedule 28.05.2013
comment
@Rob: я также использую автомакет для поддержки iPhone 5. Я мог бы решить это и без автомакета, но мне все равно нужна была бы 3-я раскадровка, и, возможно, в будущем использование автомакета может быть преимуществом.   -  person Linard Arquint    schedule 29.05.2013
comment
Как вы заметили, вам не нужен автомакет для поддержки iPhone 5. Одновременное использование как автомакета, так и неавтоматического макета удваивает ваши усилия без видимой выгоды. Не поймите меня неправильно: Autolayout предлагает несколько замечательных функций, но лично я бы не советовал использовать его до тех пор, пока вы не захотите отказаться от обратной совместимости с iOS 5. Если вы действительно хотите, используйте свой двойной подход с автоматическим и неавтоматическим расположением, но мне кажется, что это дополнительная работа с небольшой пользой. Я бы посоветовал использовать автомакет только для приложений iOS 6+.   -  person Rob    schedule 29.05.2013
comment
@Rob: я понимаю твою точку зрения. Мое текущее обновление имеет обратную совместимость с iOS 5, но я думаю, что с выходом iOS 7 я буду поддерживать только iOS 6 и 7.   -  person Linard Arquint    schedule 29.05.2013


Ответы (1)


#if — это директива препроцессора времени компиляции, она не действует после компиляции. То, что делает ваш фрагмент кода, включает определение только в том случае, если __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONENSLayoutConstraint0 истинно, поэтому, поскольку вы установили минимум для iOS 5, это объявление никогда не будет включено.

Однако решение вашей проблемы простое - ничего не делайте, по крайней мере, с этим объявлением. В iOS/OS X используется слабая компоновка, поэтому вы можете скомпилировать код для платформы/типа, который доступен только в iOS 6, и код будет успешно загружаться и выполняться в iOS 5, при условии, что вы тестируете тип, который был загружен. Вы можете проверить, загружен ли тип, вызвав метод class для типа, он вернет nil, если тип не загружен.

Таким образом, в вашем коде вы сначала опускаете #if вокруг своего объявления, а затем код, который использует NSLayoutConstraint, должен быть заключен в условное выражение, которое выполняется только в том случае, если тип существует. Что-то типа:

NSLayoutConstraint *exampleConstraint;
...

BOOL haveNSLayoutConstraint = [NSLayoutConstraint class] != nil;
...

if( haveNSLayoutConstraint )
{
   ... exampleConstraint ...
}
person CRD    schedule 28.05.2013
comment
Большое спасибо за ответ. Если я правильно вас понял, просто строка 'NSLayoutConstraint *exampleConstraint;' не создает исключения. Это правда? - person Linard Arquint; 29.05.2013