Как iOS 7 реализует элементы пользовательского интерфейса, чтобы они выглядели по-разному в зависимости от того, с какими SDK вы скомпилируете? - программирование
Подтвердить что ты не робот

Как iOS 7 реализует элементы пользовательского интерфейса, чтобы они выглядели по-разному в зависимости от того, с какими SDK вы скомпилируете?

Есть такие элементы, как UITableView s, UINavigationBar, которые имеют другой стиль для iOS 7.

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

Итак, можно подумать, что любое приложение, запущенное на iOS 7, будет иметь эти элементы, которые выглядят так, как они выглядят на iOS 7. Однако они сохраняют тот же стиль, что и у них на iOS 6, пока вы не скомпилируете с iOS 7 SDK, За исключением некоторых из них (например, UIAlertView или UIMenuController)

Моим единственным объяснением этого является то, что они делают что-то вроде этого:

#define SDKApplicationWasLinkedAgainst ...
if (SDKApplicationWasLinkedAgainst < 7.0)
    ...
else
    ...

Это, очевидно, очень громоздко, потому что им нужно поддерживать много старого кода. Так что мне любопытно, это действительно то, что происходит под капотом? Что мне не хватает?

4b9b3361

Ответ 1

Не перейдя слишком много на территорию NDA, я бы просто хотел сказать, что да, они обусловливают внешний вид и поведение, основанное на результате следующего вызова:

_UIApplicationUsesLegacyUI()

Эта функция, в свою очередь, делает вызов GSApplicationUsesLegacyUI(), который, как я полагаю, возвращает результат, основанный на версии связанного UIKit.

Это означает, что да, они обусловливают части UIKit для наследия. Не уверен, что это хорошо, но то, что они решили сделать.

Ответ 2

Моя ставка заключается в том, что они используют версии совместимости с картой.

Каждый раз, когда вы компилируете свое приложение, ваше приложение связано с определенной структурой, с версией совместимости и текущей версией. Вы можете увидеть эти числа, если вы запустите otool -L YourApp.app/YourApp. Например, для приложения, скомпилированного некоторое время назад, я получил следующее:

/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 751.58.0)
/System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 1500.0.0)

Как вы видите, полный путь к структуре UIKit хранится в двоичном формате Mach-O по нескольким версиям (и, в частности, к той версии, которую я скомпилировал в данный момент).

Я предполагаю, что в iOS 7 будет включена и версия UIKit: одна из iOS6, помеченная соответствующей версией, и совместимость с 1.0.0, а другая из iOS7, помеченная как совместимая с чем-то выше 1500.0.0 (я не знаете, если это номер для iOS 6.1.3, но вы получите идею).

Когда ваш бинарный файл iOS6 загружен, его зависимости библиотеки читаются dyld и разрешены, потому что вы были скомпилированы, говоря current version 1500.0.0, а библиотека для iOS 7 говорит compatibility version 1501.0.0, вы будете связаны с библиотекой для iOS 6.

Поскольку фреймворк также является пакетом, все ресурсы прекрасно содержатся и будут использоваться только в правильной версии, и это значит, что различные визуальные элементы будут выглядеть по-другому, если вы скомпилируете IOS 6 SDK или iOS 7 SDK.

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

Ответ 3

Я не могу быть уверен, но это одно предположение о том, как это делается. Поскольку они знают, с какой версией SDK было связано ваше приложение, они выходят из системы на устройствах iOS 7. Таким образом, в файловой системе существует иерархия по строкам /.../iPhoneOS6.1.sdk/.../Frameworks/UIKit. Затем, когда он загружает ваше приложение, они могут просто установить путь поиска для библиотек, чтобы указать на какой SDK ваше приложение было связано.

Вот как Xcode делает это прямо сейчас. Внутри каталога Developer внутри пакета Xcode находится каталог SDKs, который, в свою очередь, содержит все разные SDK для ссылки.