博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Swift3、4中的@objc、@objcMembers和dynamic
阅读量:6150 次
发布时间:2019-06-21

本文共 2273 字,大约阅读时间需要 7 分钟。

背景

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推断。

@objcMembersclass 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}@objcMembersclass 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}复制代码

参考:

转载地址:http://qlzfa.baihongyu.com/

你可能感兴趣的文章
amazeui学习笔记一(开始使用2)--布局示例layouts
查看>>
c#中lock的使用(用于预约超出限额的流程)
查看>>
ODI基于源表时间戳字段获取增量数据
查看>>
并发容器之CopyOnWriteArrayList(转载)
查看>>
什么是AAC音频格式 AAC-LC 和 AAC-HE的区别是什么
查看>>
原创:goldengate从11.2升级到12.1.2
查看>>
Quartz
查看>>
正则表达式的语法规则
查看>>
C#一个关于委托和事件通俗易懂的例子
查看>>
类似于SVN的文档内容差异对比工具winmerge
查看>>
Cause: java.sql.SQLException: The user specified as a definer ('root'@'%') does not exist
查看>>
quratz线程
查看>>
execnet: rapid multi-Python deployment
查看>>
windows修改3389端口
查看>>
关于JavaScript词法
查看>>
FreeSwitch中的会议功能(4)
查看>>
【转】adns解析库——域名解析实例(C++、linux)
查看>>
通过Performance Log确定磁盘有性能问题?
查看>>
HDOJ 2828 Lamp DLX反复覆盖
查看>>
Node.js 读取博客首页并获得文章标题
查看>>