Swift3、4中的@objc、@objcMembers和dynamic

栏目: Objective-C · 发布时间: 5年前

内容简介:Objective-C 对象是基于运行时的,方法或属性使用动态派发 ,在运行调用时再决定实际调用的具体实现。而 Swift 为了追求性能,如果没有特殊需要的话,是不会在运行时再来决定这些的。也就是说,Swift 类型的成员或者方法在编译时就已经决定,而运行时便不再需要经过一次查找,而可以直接使用。Objective-C 中所有类都继承自Swift4 后继承自

Objective-C 对象是基于运行时的,方法或属性使用动态派发 ,在运行调用时再决定实际调用的具体实现。而 Swift 为了追求性能,如果没有特殊需要的话,是不会在运行时再来决定这些的。也就是说,Swift 类型的成员或者方法在编译时就已经决定,而运行时便不再需要经过一次查找,而可以直接使用。

Objective-C 中所有类都继承自 NSObject ,Swift 中的类如果要供 Objective-C 调用,必须也继承自 NSObject

@objc

  1. @objc 修饰符的根本目的是用来暴露接口给 Objective-C 的运行时(类、协议、属性和方法等)

  2. 添加 @objc 修饰符并不意味着这个方法或者属性会采用 Objective-C 的方式变成动态派发,Swift 依然可能会将其优化为静态调用

  3. @objc 修饰符的隐式添加:

    • Swift 3 中继承自 NSObject 的类,不需要手动添加 @objc ,编译器会给所有的非 private 的类和成员加上 @objcprivate 接口想要暴露给 Objective-C 需要 @objc 的修饰

      button.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)
      @objc private func backButtonTapped() { }
      func backButtonTapped() { }
      复制代码
    • Swift 4 中继承自 NSObject 的类的隐式 @objc 自动添加,只会发生在以下四种情况:

      • 重写了父类的 Objective-C 方法
      • 实现了一个 Objective-C 的协议
      • @IBAction@IBOutlet 关键字的修饰
      • @NSManaged 关键字的修饰
  4. 使用 @objc 可以修改 Swift 接口暴露到 Objective-C 后的名字

    @objc(Squirrel)
    class Белка: NSObject {
        @objc(color)
        var цвет: Цвет = .Красный
    
        @objc(hideNuts:inTree:)
        func прячьОрехи(количество: Int, вДереве дерево: Дерево) { }
    }
    复制代码

@objcMembers

Swift4 后继承自 NSObject 的类不再隐式添加 @objc 关键字,但在某些情况下非常依赖 Objective-C 的运行时(如 XCTest),所以在 Swift4 中提供了 @objcMembers 关键字,对类和子类、扩展和子类扩展重新启用 @objc 推断。

@objcMembers
class MyClass : NSObject {
  func foo() { }             // implicitly @objc

  func bar() -> (Int, Int)   // not @objc, because tuple returns
      // aren't representable in Objective-C
}

extension MyClass {
  func baz() { }   // implicitly @objc
}

class MySubClass : MyClass {
  func wibble() { }   // implicitly @objc
}

extension MySubClass {
  func wobble() { }   // implicitly @objc
}
复制代码

使用 @objc@nonobjc 可以指定开启或关闭某一 extension 中的所有方法的 @objc 推断。

class SwiftClass { }

@objc extension SwiftClass {
  func foo() { }            // implicitly @objc
  func bar() -> (Int, Int)  // error: tuple type (Int, Int) not
      // expressible in @objc. add @nonobjc or move this method to fix the issue
}

@objcMembers
class MyClass : NSObject {
  func wibble() { }    // implicitly @objc
}

@nonobjc extension MyClass {
  func wobble() { }    // not @objc, despite @objcMembers
}
复制代码

dynamic

当前 Swift 的动态性依赖于 Objective-C,Swift3 中 dynamic 就隐式包含了 @objc 的意思,但考虑到以后版本的 Swift 语言和运行时将会自支持 dynamic 而不再依赖于 Objective-C,所以在 Swift4 中将 dynamic@objc 含义进行了抽离。

class MyClass {
  dynamic func foo() { }       // error: 'dynamic' method must be '@objc'
  @objc dynamic func bar() { } // okay
}
复制代码

参考: Limiting @objc inference


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

轻快的Java

轻快的Java

(美)塔特、杰兰德/国别:中国大陆 / 张晓坤 / 中国电力出版社 / 2006-7 / 29.00元

Java的开发者正深陷于复杂性的泥沼中而无法自拔。我们的经验和能力正接近极限,程序员为了编写支持所选框架的程序所花的时间比解决真正问题的时间要多得多。我们不禁要问,有必要把Java搞得这么复杂吗?   答案是否定的。本书给你指引了一条出路。无论是维护应用程序,还是从头开始设计,你都能够超越成规,并大幅精简基本框架、开发过程和最终代码。你能重新掌握一度失控的J2EE应用程序。   在本书......一起来看看 《轻快的Java》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具