swift 的缺省基类

疑问

在 Objective-C 中,NSObject 几乎是所有类的基类。那么在 swift 中存在一个这样的基类吗?

Apple 在官方的 Swift Language Guide 中说:

Swift classes do not inherit from a universal base class. Classes you define without specifying a superclass automatically become base classes for you to build upon.

Swift 中的类并不是从一个通用的基类继承而来的。如果你不为自己定义的类指定一个超类的话,这个类就会自动成为基类。

矛盾

但在 Swift 仓库文档中的 TypeLayout.rst 中可以找到这么一段话:

The root of a class hierarchy must remain stable, at pain of invalidating the metaclass hierarchy. Note that a Swift class without an explicit base class is implicitly rooted in the SwiftObject Objective-C class.

类层次结构的根必须保持稳定,否则会使元类层次结构失效。没有显式基类的 swift 类,将以一个名为 SwiftObjectObjective-C 类作为隐式基类。

也就是说真实情况并不是 Swift Language Guide 中所说的那样,那么这个 SwiftObject 具体是什么呢?从前文中我们知道了它是个 Objective-C类,那他也是继承自 NSObject 吗?

真相

swift的源码可以解决我们的疑惑!在 swift 的 runtime 中找到了 SwiftObject.h SwiftObject.mm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// This implements the Objective-C root class that provides basic `id`- 
// compatibility and `NSObject` protocol conformance for pure Swift classes.
// 实现了 Objective-C 根类,该类为纯Swift类提供了基本的id兼容性和NSObject协议一致性。
#if __has_attribute(objc_root_class)
__attribute__((__objc_root_class__))
#endif
SWIFT_RUNTIME_EXPORT @interface SwiftObject<NSObject> {
@private
// isa 指针
Class isa;
// The members of the HeapObject header that are not shared by a
// standard Objective-C instance
// InlineRefCounts 是一个相当重要东西,引用计数、弱引用、unowned 引用都与它有关
// http://www.manongjc.com/article/64837.html

// #define SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS \
// InlineRefCounts refCounts
SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS;
}
...
@end

可以看出 SwiftObject 并不是继承自 NSObject 类,而是一个遵循了 NSObject 协议的 Objective-C 根类。

从Objective-C 的 Runtime 源码中可以了解到,之所以 NSObject 和 NSProxy 是根类,是因为在类声明时添加了

__attribute__((objc_root_class))属性。但在 SwiftObject 添加的却是 __attribute__((__objc_root_class__))

两者效果一样??