弱链接-检查某个类是否存在并使用该类


87

我正在尝试创建通用的iPhone应用程序,但它使用的类仅在更新版本的SDK中定义。该框架存在于较旧的系统上,但框架中定义的类不存在。

我知道我想使用某种弱链接,但是我能找到的任何文档都涉及功能是否存在的运行时检查-如何检查类是否存在?


什么班?也许还有其他解决方法。
Marcelo Cantos

Answers:


164

TLDR

当前:

  • 斯威夫特if #available(iOS 9, *)
  • iOS的Obj-Cif (@available(iOS 11.0, *))
  • Obj-C,OS Xif (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])

迅捷2+

尽管从历史上看,建议您检查功能(或类是否存在)而不是特定的OS版本,但由于引入了以下功能,因此在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()如果存在[the]类,则将使用该类 返回有效的类对象;如果不存在,则返回nil。如果该类确实存在,则您的代码可以使用它[...]


谢谢。只是为了完成对他人的回答,一旦检测到该类,便使用(ClassNSClassFromString分配给id)返回的实例创建该类,并在该实例上调用选择器。
psychotik 2010年

2
值得注意的是,这是可行的,但这是OSX上的唯一方法,而不是iOS(4.2+)上的“最佳”方法。具体参见iOS的code007答案。
Ben Mosher 2013年

如果我的课程不是真正的课程而是C结构,该怎么办?
内森H

Swift 4.1进行了新的检查canImport提案
dispatchMain

69

对于使用iOS 4.2或更高版本的基本SDK的新项目,建议使用这种新方法,即使用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.
}

来源:https : //developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/cross_development/Using/using.html#//apple_ref/doc/uid/20002000-SW3

此机制使用NS_CLASS_AVAILABLE宏,该宏可用于iOS中的大多数框架(请注意,可能有些框架尚不支持NS_CLASS_AVAILABLE-请查看iOS发行说明)。可能还需要额外的设置配置,可以从上面提供的Apple文档链接中读取该设置,但是,此方法的优点是可以进行静态类型检查。


3
游戏UIAlertController还算晚一点,但是当我尝试构建仍支持iOS 7的代码时遇到了这个问题。code007的答案是正确的,但是所需的额外配置是在项目中弱链接(设置RequiredOptional)UIKit。 (至少在这种情况下)。
埃文·R
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.