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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3057325/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:21:02  来源:igfitidea点击:

Weak Linking - check if a class exists and use that class

iosbackwards-compatibilityweak-linking

提问by psychotik

I'm trying to create a universal iPhone app, but it uses a class defined only in a newer version of the SDK. The framework exists on older systems, but a class defined in the framework doesn't.

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

I know I want to use some kind of weak linking, but any documentation I can find talks about runtime checks for function existence - how do I check that a class exists?

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

回答by Senseful

TLDR

TLDR

Current:

当前的:

  • Swift: if #available(iOS 9, *)
  • Obj-C, iOS: if (@available(iOS 11.0, *))
  • Obj-C, OS X: if (NSClassFromString(@"UIAlertController"))
  • 斯威夫特if #available(iOS 9, *)
  • OBJ-C,iOS版if (@available(iOS 11.0, *))
  • Obj-C,OS Xif (NSClassFromString(@"UIAlertController"))

Legacy:

遗产:

  • Swift (versions prior to 2.0): if objc_getClass("UIAlertController")
  • Obj-C, iOS (versions prior to 4.2): if (NSClassFromString(@"UIAlertController"))
  • Obj-C, iOS (versions prior to 11.0): if ([UIAlertController class])
  • 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+

斯威夫特 2+

Although historically it's been recommended to check for capabilities (or class existence) rather than specific OS versions, this doesn't work well in Swift 2.0 because of the introduction of availability checking.

尽管历史上建议检查功能(或类是否存在)而不是特定的操作系统版本,但由于引入了可用性检查,这在 Swift 2.0 中效果不佳。

Use this way instead:

改用这种方式:

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(...)
}

Note:If you instead attempt to use objc_getClass(), you will get the following error:

注意:如果您尝试使用objc_getClass(),您将收到以下错误:

?? 'UIAlertController' is only available on iOS 8.0 or newer.

?? “UIAlertController”仅适用于 iOS 8.0 或更新版本。



Previous versions of Swift

以前版本的 Swift

if objc_getClass("UIAlertController") != nil {
    let alert = UIAlertController(...)
} else {
    let alert = UIAlertView(...)
}

Note that objc_getClass()is more reliable than NSClassFromString()or objc_lookUpClass().

请注意,这objc_getClass()NSClassFromString()或更可靠objc_lookUpClass()



Objective-C, iOS 4.2+

目标-C,iOS 4.2+

if ([SomeClass class]) {
    // class exists
    SomeClass *instance = [[SomeClass alloc] init];
} else {
    // class doesn't exist
}

See code007's answer for more details.

有关更多详细信息,请参阅code007 的回答



OS X or previous versions of iOS

OS X 或之前版本的 iOS

Class klass = NSClassFromString(@"SomeClass");
if (klass) {
    // class exists
    id instance = [[klass alloc] init];
} else {
    // class doesn't exist
}

Use NSClassFromString(). If it returns nil, the class doesn't exist, otherwise it will return the class object which can be used.

使用NSClassFromString(). 如果返回nil,则该类不存在,否则返回可以使用的类对象。

This is the recommended way according to Apple in this document:

这是 Apple 在本文档中推荐的方式:

[...] Your code would test for the existence of [a] class using NSClassFromString()which will return a valid class object if [the] class exists or nil if it doesn?t. If the class does exist, your code can use it [...]

[...] 您的代码将测试 [a] 类是否存在, NSClassFromString()如果 [该] 类存在,它将返回一个有效的类对象,如果不存在,则返回 nil。如果该类确实存在,您的代码可以使用它 [...]

回答by code007

For new projects that uses a base SDK of iOS 4.2 or later, there is this new recommended approach which is to use the NSObject class method to check the availability of weakly linked classes at run time. i.e.

对于使用 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.
}

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

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

This mechanism uses the NS_CLASS_AVAILABLE macro, which is available for mostframework in iOS (note there may be some framework that do not yet support the NS_CLASS_AVAILABLE - check the iOS release note for this). Extra setting configuration may also be needed that can be read in the Apple's documentation link provided above, however, the advantage of this method is that you get static type checking.

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