Swift和Objc的互操作性-可用性仅在objc中不起作用

生活

虽然这里的苹果指出,斯威夫特available标志应在objc也适用,它不是为我工作。我究竟做错了什么?


我在Swift文件中有以下声明:

@objc protocol Readable: AnyObject {...}

@available(iOS 10.3, *)
@objc class Reader: NSObject, Readable {...}

因此,当我尝试在没有版本检查的ios-10之前的项目中初始化它时,让我们检查它是否产生错误。如果我在Swift中编写以下代码:

let tmp = Reader()

它返回一个错误:

“阅读器”仅在iOS 10.3或更高版本上可用

期望什么。


但是,如果我在objc中编写以下代码:

// if (@available(iOS 10.3, *)) { // commeted out to test if it succeeds without version check
    Reader *tmp = [[Reader alloc] init];
// }

构建完成没有任何错误,而我期望与Swift中相同的错误。


我尝试用以下方式标记课程:

  • @available(iOS 11,*)
  • @available(iOS,引入:10.3)

这些都不在objc中工作(产生错误)。有什么帮助吗?

ne

Objective-C__attribute__((availability))的时间比它的时间长@available为了使其正常工作,Objective-C编译器弱链接了部署目标上不可用的符号。这意味着编译总是成功,并且启动您的应用程序也会成功,但是如果该符号不可用,则它将在运行时为NULL。

取决于它是什么,尝试使用它时,您会或多或少地得到适当的降级:

  • 调用缺少的弱链接函数将会崩溃
  • 读取或写入丢失的全局变量将崩溃
  • 使用缺少的类将是无操作,并且所有方法都将返回零

测试在运行时是否找到符号的旧方法只是将其与NULL比较:

NS_AVAILABLE_MAC(...) @interface Foo @end
int bar NS_AVAILABLE_MAC(...);
int baz(int frob) NS_AVAILABLE_MAC(...);

if ([Foo class]) { /* Foo is available */ }
if (&bar) { /* bar is available */ }
if (&baz) { /* baz is available */ }

在您的情况下:

Reader *tmp = [[Reader alloc] init];

tmp会的nil,因为那会和[[nil alloc] init]

@available指令直到最近才被添加到Objective-C中。现在可以@available#available在Swift中一样在Objective-C中使用它。但是,为了保持向后兼容性,尝试使用在Objective-C的部署目标上可能不可用的符号,可能永远不会是编译时错误(默认错误级别)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章