Swift本地基类或NSObject

我testing了一些与Swift混合的isa ,发现它只有在NSObject是一个超级类(直接或更高级)或者使用'@objc'装饰时才起作用。 否则,它将遵循静态和虚表分发风格,如C ++。

定义一个没有Cocoa / NSObject基类的Swift类是正常的吗? 如果是我所关心的,这意味着Objective-C的许多dynamic性,比如方法拦截和运行时自省。

dynamic运行时行为是属性观察者,核心数据, 面向方面编程 , 高级消息传递 ,分析和日志框架等function的核心。

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

但是,考虑到一般的95-5规则( 性能增益的95%来自调整代码的5% ),从强大的dynamic特性开始并在必要时加强是不合理的?

Swift类是NSObject的子类:

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

Swift类不是NSObject的子类:

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

在Swift中使用NSObject可以获得Objective-C运行时的灵活性,而且还可以获得Objective-C的性能。 如果您不需要Objective-C的灵活性,避免NSObject可以提高性能。

编辑:

随着Xcode 6 beta 6,dynamic属性出现。 这允许我们指示Swift一个方法应该使用dynamic调度,因此将支持拦截。

 public dynamic func foobar() -> AnyObject { } 

我还发现,如果基于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 } } } 

在这个例子中,我们基于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 } } } 

我想道德是,只有基于NSObject你真的必须!

根据语言参考,没有要求类inheritance任何标准的根类,所以你可以根据需要包含或省略一个超类。

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

从语言参考:

Swift类不会从通用基类inheritance。 你定义的类没有指定超类自动成为基础类,你要build立。

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

 'super' members cannot be referenced in a root class 

我相信绝大多数Swift数据都不会是objc 。 只有那些需要与Objective C基础设施进行通信的部分才会被明确标记。

我不知道在哪个范围内将运行时反思添加到语言中。 如果方法明确允许的话,方法拦截可能会变得可能。 这是我的猜测,但是只有苹果公司的语言devise师才真正知道他们在哪里。

下面是从苹果的Swift电子书复制,并给出了一个适当的答案你的问题:

定义一个基类

任何不从另一个类inheritance的类都称为基类。

Swift类不会从通用基类inheritance。 你定义的类没有指定超类自动成为基础类,你要build立。

参考

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html#//apple_ref/doc/uid/TP40014097-CH17-XID_251

这是正常的。 看看Swift的devise目标:目标是让大量的编程问题消失。 Swizzling方法可能不是你想要用Swift做的事情之一。