88

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

我知道我想使用某种弱链接,但是我能找到的任何文档都谈到了函数存在的运行时检查——我如何检查一个类是否存在?

4

2 回答 2

165

TLDR

当前的:

  • 斯威夫特if #available(iOS 9, *)
  • 对象-C,iOSif (@available(iOS 11.0, *))
  • 对象-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+

尽管历史上建议检查功能(或类是否存在)而不是特定的操作系统版本,但由于引入了可用性检查,这在 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()orobjc_lookUpClass()更可靠。


目标-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。如果该类确实存在,您的代码可以使用它 [...]

于 2010-06-16T21:31:14.093 回答
69

对于使用 iOS 4.2 或更高版本的基础 SDK 的新项目,有一种新的推荐方法,即使用 NSObject 类方法在运行时检查弱链接类的可用性。IE

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 文档链接中阅读,但是,这种方法的优点是您可以获得静态类型检查。

于 2012-04-09T01:41:49.233 回答