Swift本机基类或NSObject

Jas*_*ues 101 objective-c objective-c-runtime swift

我测试了一些ISA混写有斯威夫特,以及时发现NSObject的是一个超类(直接或进一步上涨),或使用"@objc"的装饰,它才会起作用.否则它将遵循静态和vtable-dispatch样式,如C++.

没有Cocoa/NSObject基类定义Swift类是正常的吗?如果它是我关心的话,这意味着对Objective-C的大部分动力进行了描述,例如方法拦截和运行时内省.

动态运行时行为是属性观察者,核心数据,面向方面编程,高阶消息传递,分析和日志记录框架等功能的核心.

使用Objective-C的方法调用样式会在方法调用中添加大约20个机器代码操作数,因此在某些情况下(对具有小体的方法的许多严格调用)C++样式静态和vtable调度可以更好地执行.

但是考虑到一般的95-5规则(95%的性能增益来自调整5%的代码),从强大的动态功能开始并在必要时变硬是不是有意义的?

Gre*_*ker 103

Swift类是NSObject的子类:

  • 是Objective-C类本身
  • 使用objc_msgSend()的调用(大部分)的方法
  • 为(大多数)方法实现提供Objective-C运行时元数据

不是NSObject子类的Swift类:

  • 是Objective-C类,但只实现了少数NSObject兼容性方法
  • 不要objc_msgSend()用于调用他们的方法(默认情况下)
  • 不为其方法实现提供Objective-C运行时元数据(默认情况下)

在Swift中对NSObject进行子类化可以获得Objective-C运行时灵活性以及Objective-C性能.如果您不需要Objective-C的灵活性,避免使用NSObject可以提高性能.

编辑:

使用Xcode 6 beta 6,将显示动态属性.这允许我们指示Swift方法应该使用动态分派,因此将支持拦截.

public dynamic func foobar() -> AnyObject {
}
Run Code Online (Sandbox Code Playgroud)

  • Swift可以使用objc_msgSend调度,虚拟表调度,直接调度或内联. (11认同)

Pet*_*ete 14

我还发现,如果在NSObject上建立Swift类,我会看到一些意外的运行时行为,可能会隐藏编码错误.这是一个例子.

在这个例子中,我们没有基于NSObject,编译器正确地发现了testIncorrect_CompilerShouldSpot中的错误,报告"......'MyClass'不能转换为'MirrorDisposition'"

class MyClass {
  let mString = "Test"

  func getAsString() -> String {
    return mString
  }

  func testIncorrect_CompilerShouldSpot() {
    var myString = "Compare to me"
      var myObject = MyClass()
      if (myObject == myString) {
        // Do something
      }
  }

  func testCorrect_CorrectlyWritten() {
    var myString = "Compare to me"
      var myObject = MyClass()
      if (myObject.getAsString() == myString) {
        // Do something
      }
  }
}
Run Code Online (Sandbox Code Playgroud)

在这个基于NSObject的示例中,编译器没有发现testIncorrect_CompilerShouldSpot中的错误:

class myClass : NSObject {
  let mString = "Test"

  func getAsString() -> String {
    return mString
  }

  func testIncorrect_CompilerShouldSpot() {
    var myString = "Compare to me"
      var myObject = MyClass()
      if (myObject == myString) {
        // Do something
      }
  }

  func testCorrect_CorrectlyWritten() {
    var myString = "Compare to me"
      var myObject = MyClass()
      if (myObject.getAsString() == myString) {
        // Do something
      }
  }
}
Run Code Online (Sandbox Code Playgroud)

我想道德是,只有你真正需要的NSObject!


Cez*_*zar 12

根据语言参考,不要求类继承任何标准根类,因此您可以根据需要包含或省略超类.

请注意,省略类声明中的超类,不会分配任何类型的隐式基类.它定义了一个基类,它将有效地成为独立类层次结构的根.

从语言参考:

Swift类不从通用基类继承.您在不指定超类的情况下定义的类会自动成为您构建的基类.

尝试super从没有超类(即基类)的类引用将导致编译时错误

'super' members cannot be referenced in a root class
Run Code Online (Sandbox Code Playgroud)