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

发布于 2024-09-05 22:56:27 字数 139 浏览 6 评论 0 原文

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

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

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.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

执笏见 2024-09-12 22:56:27

TLDR

当前:

  • Swiftif #available(iOS 9, *)
  • Obj-C、iOSif (@available(iOS 11.0, *))
  • Obj-C、OS X: if (NSClassFromString(@"UIAlertController"))

旧版:

  • Swift(2.0 之前的版本)if objc_getClass("UIAlertController")
  • Obj-C、iOS(4.2 之前的版本)< /strong>: 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() 将返回
一个有效的类对象,如果[the]类
存在,如果不存在则为零。如果
类确实存在,您的代码可以使用它
[...]

TLDR

Current:

  • Swift: if #available(iOS 9, *)
  • Obj-C, iOS: if (@available(iOS 11.0, *))
  • Obj-C, OS X: if (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+

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.

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:

⛔️ 'UIAlertController' is only available on iOS 8.0 or newer.


Previous versions of 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().


Objective-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.


OS X or previous versions of 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.

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

[...] 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
[...]

我很OK 2024-09-12 22:56:27

对于使用 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 文档链接中阅读,但是,此方法的优点是您可以进行静态类型检查。

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.

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

This mechanism uses the NS_CLASS_AVAILABLE macro, which is available for most framework 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文