Swift 3:是否子类化 NSObject?

问题描述 投票:0回答:4

我读过一些像 this one 这样的文章,关于 Swift 中的子类化

NSObject
与仅拥有其原生基础
class
而没有子类化之间的区别。但都是有点老的帖子了,我对这个话题不太清楚。

什么时候应该子类化

NSObject
?子类化和不子类化之间的实际区别是什么?目前 Swift 的推荐是什么?

swift class inheritance subclass nsobject
4个回答
24
投票

Apple 关于 NSObject 的文档有以下介绍:

NSObject 是大多数 Objective-C 类层次结构的根类。通过 NSObject,对象继承了运行时系统的基本接口以及作为 Objective-C 对象运行的能力。

正如这表明的那样,每当该类型的实例需要表现得像 Objective-C 对象(或类本身,在某些罕见的情况下)时,您需要为代码中引入的类型创建 NSObject 子类。

我不知道苹果是否提供了关于何时子类化 NSObject 的超级明确的书面指导,除了建议减少动态调度或使用不依赖于子类化而是协议扩展(即代码)来呈现代码重用范例重用通常更静态调度和值类型友好)。我相信可以公平地说,大多数 Swift 程序员都从 Apple 那里得到了暗示,并且 Swift 语言特性作为标志,在没有上述需求时避免引入基于 NSObject 的类型。 也就是说,作为一般规则,仅在您实际需要 Objective-C 动态性时才引入基于 NSObject 的类型,最常见的是当您需要与 Cocoa API 交互时(尤其是当您的代码与 UI 相关时常见:例如视图控制器、视图) .

正如您链接到的问题的答案中所指出的,Objective-C 风格的活力带来了基于

objc_msgSend
的方法调度的性能。尽管 Swift 类中的方法也是虚拟的,但当您没有使用
@objc
属性显式标记方法时,编译器能够使用更快的方法来分派方法 - 特别是当 Whole Module Optimization 打开时 ,甚至更多所以在 Swift 3 中,类默认不开放用于定义类型的模块之外的子类化

除了避免使用 NSObject 之外,在编写 Swift 时,在很多情况下你还可以完全避免基于类的引用类型。例如,请查看上面链接的价值类型 WWDC 视频,或者例如作为介绍的此博文。简而言之,使用值类型可以获得良好的本地推理,通常可以避免动态内存分配和引用计数开销(尽管并非普遍如此 - 具有引用类型作为字段的结构是警告)。


2
投票

子类化 NSObject 的一个原因是如果您需要保存一些数据。 NSObject 及其所需的一切仍然是(AFAIK)获取需要写入文件的 NSCoding 的最简单方法。

一些见解可以在这里这里

找到

1
投票

您必须子类化的另一种情况

NSObject
是当您希望您的子类成为 KVO 的观察者时,即

addObserver(_ observer: NSObject, forKeyPath keyPath: String, options: NSKeyValueObservingOptions = [], context: UnsafeMutableRawPointer?)

要求观察者是一个

NSObject
(或者数组或集合)。


0
投票

斯威夫特 4.1 更新

在 Swift 4.1 中,不推荐使用类来限制引用类型的协议一致性,而是使用 AnyObject。现在,我们应该使用 AnyObject 作为协议继承,以确保只有类类型才能符合给定的协议。

为什么使用 AnyObject?

我。限制引用类型(仅限类):通过从 AnyObject 继承,该协议只能被类类型采用,不包括结构体和枚举。当您需要类独有的功能(例如引用语义)时,这特别有用。

二.使用弱引用:创建委托时,经常使用弱引用来防止强引用循环。弱引用仅允许用于类类型,这使得 AnyObject 对于定义委托协议至关重要。 如果没有 AnyObject,则无法声明对协议类型的弱引用,因为弱引用仅适用于类

protocol MyProtocol: AnyObject {
    func doSomething()
}

class MyClass: MyProtocol {
    func doSomething() {
        print("Doing something")
    }
}

class AnotherClass {
    weak var delegate: MyProtocol?  // Works because MyProtocol inherits from AnyObject
}
© www.soinside.com 2019 - 2024. All rights reserved.