Слабая связь-проверьте, существует ли класс и используйте этот класс
Я пытаюсь создать универсальное приложение для iPhone, но оно использует класс, определенный только в более новой версии SDK. Фреймворк существует в старых системах, но класс, определенный в фреймворке, не существует.
Я знаю, что хочу использовать какую - то слабую связь, но любая документация, которую я могу найти, говорит о проверке времени выполнения для существования функции-как я могу проверить, что класс существует?
2 ответа:
TLDR
ток:
- Swift:
if #available(iOS 9, *)
- Obj-C, iOS:
if (@available(iOS 11.0, *))
- Obj-C, OS X:
if (NSClassFromString(@"UIAlertController"))
наследие:
- Swift (версии до 2.0):
if objc_getClass("UIAlertController")
- Obj-C, iOS (версии до 4.2):
if (NSClassFromString(@"UIAlertController"))
- Obj-C, iOS (версии до 11.0):
if ([UIAlertController class])
Swift 2+
хотя исторически было рекомендовано проверять возможности (или существование класса), а не конкретные версии ОС, это не очень хорошо работает в Swift 2.0 из-за введения доступность проверки.
использовать этот способ вместо:
if #available(iOS 9, *) { // You can use UIStackView here with no errors let stackView = UIStackView(...) } else { // Attempting to use UIStackView here will cause a compiler error let tableView = UITableView(...) }
Примечание: если вы вместо этого попробуйте использовать
objc_getClass()
, вы получите следующее сообщение об ошибке:️ 'UIAlertController' доступен только на iOS 8.0 или новее.
предыдущие версии Swift
if objc_getClass("UIAlertController") != nil { let alert = UIAlertController(...) } else { let alert = UIAlertView(...) }
отметим, что
objc_getClass()
надежнее, чемNSClassFromString()
илиobjc_lookUpClass()
.
Objective-C, iOS 4.2+
if ([SomeClass class]) { // class exists SomeClass *instance = [[SomeClass alloc] init]; } else { // class doesn't exist }
посмотреть ответ code007 для больше подробности.
OS X или предыдущие версии iOS
Class klass = NSClassFromString(@"SomeClass"); if (klass) { // class exists id instance = [[klass alloc] init]; } else { // class doesn't exist }
использовать
NSClassFromString()
. Если он возвращаетnil
класс не существует, в противном случае он возвращает объект класса, который может быть использован.это рекомендуемый способ в соответствии с Apple в документ:
[...] Ваш код будет тестировать для существование класса [a] с использованием
NSClassFromString()
что вернется допустимый класс объект, если [] класс существует или нет, если это не так. Если класс существует, ваш код может его использовать [...]
для новых проектов, использующих базовый SDK iOS 4.2 или более поздней версии, существует этот новый рекомендуемый подход, который заключается в использовании метода класса NSObject для проверки доступности слабо связанных классов во время выполнения. то есть
if ([UIPrintInteractionController class]) { // Create an instance of the class and use it. } else { // Alternate code path to follow when the // class is not available. }
этот механизм использует макрос NS_CLASS_AVAILABLE, который является доступно для большинство framework в iOS (Примечание могут быть некоторые рамки, которые еще не поддерживают NS_CLASS_AVAILABLE - проверьте примечание к выпуску iOS для этого). Также может потребоваться дополнительная настройка конфигурации, которую можно прочитать в приведенной выше ссылке документации Apple, однако преимущество этого метода заключается в том, что вы получаете статическую проверку типа.