Swift 3: NSObject 的子类化与否?
Swift 3: subclassing NSObject or not?
我读过一些帖子,例如 this one,关于在 Swift 中子类化 NSObject
或仅拥有其原生基础 class
而没有子类化之间的区别。不过都是些老帖子了,我也不清楚这个话题。
什么时候应该继承 NSObject
?继承它和不继承它之间的实际区别是什么? Swift 目前的建议是什么?
Apple's documentation about NSObject 声明如下作为介绍:
NSObject is the root class of most Objective-C class hierarchies. Through NSObject, objects inherit a basic interface to the runtime system and the ability to behave as Objective-C objects.
正如这所暗示的那样,只要代码中引入的类型的实例需要表现得像 Objective-C 对象(或 class 本身,在极少数情况下)。
我不知道 Apple 提供了关于何时 不 子 class NSObject 的书面指导,超越 suggesting reducing dynamic dispatch or presenting code reuse paradigms using that do not relying on subclassing but protocol extensions, i.e. code reuse that is generally more static dispatch and value type 友好)。我相信可以公平地说,尽管大多数 Swift 程序员都从 Apple 那里得到了提示,并且 Swift 语言特性作为避免在上述需求不存在时引入基于 NSObject 的类型的标志。 也就是说,作为一般规则,只有在您实际需要 Objective-C 动态时才引入基于 NSObject 的类型,最常见的是当您需要与 Cocoa API 接口时(尤其是当您的代码UI 相关:例如视图控制器、视图)。
As pointed out in an answer to the question you link to, with Objective-C style dynamism comes the performance of objc_msgSend
based method dispatch. Although methods in Swift classes are also virtual, the compiler is able to use faster means of dispatching methods when you don't explicitly mark the methods with the @objc
attribute – especially when Whole Module Optimization is toggled on, and even more so in Swift 3 where classes are not by default open for subclassing beyond the module that defines the type。
除了避免 NSObject 之外,您还可以完全避免基于 class 的引用类型 in many cases when writing Swift. Take a look at for instance the value type WWDC videos linked above, or for example this blog post 作为介绍。简而言之,使用值类型可以获得良好的本地推理,通常可以避免动态内存分配和引用计数开销(尽管并非普遍如此——需要注意的是将引用类型作为字段的结构)。
将 NSObject 子类化的一个原因是您需要保存一些数据。 NSObject 及其所有内容仍然是(AFAIK)获取 NSCoding 的最简单方法,您需要将其写入文件。
可以找到一些见解here or here
另一种你必须继承 NSObject
的情况是当你希望你的子类成为 KVO 的观察者时,即
addObserver(_ observer: NSObject, forKeyPath keyPath: String, options: NSKeyValueObservingOptions = [], context: UnsafeMutableRawPointer?)
要求观察者是NSObject
(或数组或集合)。
我读过一些帖子,例如 this one,关于在 Swift 中子类化 NSObject
或仅拥有其原生基础 class
而没有子类化之间的区别。不过都是些老帖子了,我也不清楚这个话题。
什么时候应该继承 NSObject
?继承它和不继承它之间的实际区别是什么? Swift 目前的建议是什么?
Apple's documentation about NSObject 声明如下作为介绍:
NSObject is the root class of most Objective-C class hierarchies. Through NSObject, objects inherit a basic interface to the runtime system and the ability to behave as Objective-C objects.
正如这所暗示的那样,只要代码中引入的类型的实例需要表现得像 Objective-C 对象(或 class 本身,在极少数情况下)。
我不知道 Apple 提供了关于何时 不 子 class NSObject 的书面指导,超越 suggesting reducing dynamic dispatch or presenting code reuse paradigms using that do not relying on subclassing but protocol extensions, i.e. code reuse that is generally more static dispatch and value type 友好)。我相信可以公平地说,尽管大多数 Swift 程序员都从 Apple 那里得到了提示,并且 Swift 语言特性作为避免在上述需求不存在时引入基于 NSObject 的类型的标志。 也就是说,作为一般规则,只有在您实际需要 Objective-C 动态时才引入基于 NSObject 的类型,最常见的是当您需要与 Cocoa API 接口时(尤其是当您的代码UI 相关:例如视图控制器、视图)。
As pointed out in an answer to the question you link to, with Objective-C style dynamism comes the performance of objc_msgSend
based method dispatch. Although methods in Swift classes are also virtual, the compiler is able to use faster means of dispatching methods when you don't explicitly mark the methods with the @objc
attribute – especially when Whole Module Optimization is toggled on, and even more so in Swift 3 where classes are not by default open for subclassing beyond the module that defines the type。
除了避免 NSObject 之外,您还可以完全避免基于 class 的引用类型 in many cases when writing Swift. Take a look at for instance the value type WWDC videos linked above, or for example this blog post 作为介绍。简而言之,使用值类型可以获得良好的本地推理,通常可以避免动态内存分配和引用计数开销(尽管并非普遍如此——需要注意的是将引用类型作为字段的结构)。
将 NSObject 子类化的一个原因是您需要保存一些数据。 NSObject 及其所有内容仍然是(AFAIK)获取 NSCoding 的最简单方法,您需要将其写入文件。
可以找到一些见解here or here
另一种你必须继承 NSObject
的情况是当你希望你的子类成为 KVO 的观察者时,即
addObserver(_ observer: NSObject, forKeyPath keyPath: String, options: NSKeyValueObservingOptions = [], context: UnsafeMutableRawPointer?)
要求观察者是NSObject
(或数组或集合)。