代码之家  ›  专栏  ›  技术社区  ›  Nat

swift和objc互操作性-可用性不仅在objc中有效

  •  1
  • Nat  · 技术社区  · 6 年前

    同时 here 苹果声称 available 标记也应该应用于objc,它对我不起作用。我做错什么了?


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

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

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

    let tmp = Reader()
    

    它返回一个错误:

    “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中出现相同的错误。


    我试着在课堂上做标记:

    • @可用(iOS 11,*)
    • @可用(iOS,推出时间:10.3)

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

    1 回复  |  直到 6 年前
        1
  •  1
  •   zneak    6 年前

    目标C已经 __attribute__((availability)) 比以前更长的时间 @available . 为了使其工作,Objective-C编译器弱链接部署目标上不可用的符号。这意味着编译总是成功的,并且启动应用程序是成功的,但是如果符号在运行时不可用,它将是空的。

    根据它是什么,当你尝试使用它时,你会或多或少地得到优雅的降级:

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

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

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

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