首先请参阅type(of:) 上的 Apple 文档
函数签名很有趣:
func type<T, Metatype>(of value: T) -> Metatype
用在什么地方?
如果您正在编写/创建一个接受 type 的函数,例如UIView.Type,不是实例,例如UIView()then 给你写 T.Type 作为参数的类型。它期望的参数可以是:String.self、CustomTableView.self、someOtherClass.self。
但是为什么函数需要类型呢?
通常一个需要类型的函数,是一个为您实例化对象的函数。我能想到两个很好的例子:
-
register 来自 tableview 的函数
tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "CustomTableViewCell")
请注意,您通过了CustomTableViewCell.self。如果稍后您尝试将 CustomTableViewCell 类型的 tableView 出列,但没有注册 CustomTableViewCell 类型,那么它会崩溃,因为 tableView 尚未出列/实例化任何 CustomTableViewCell 类型的 tableviewcells。
-
decode 函数来自 JSONDecoder。示例来自链接
struct GroceryProduct: Codable {
var name: String
var points: Int
var description: String?
}
let json = """
{
"name": "Durian",
"points": 600,
"description": "A fruit with a distinctive scent."
}
""".data(using: .utf8)!
let decoder = JSONDecoder()
let product = try decoder.decode(GroceryProduct.self, from: json)
print(product.name)
通知try decoder.decode(GroceryProduct.self, from: json)。因为你传递了GroceryProduct.self,它知道它需要实例化一个GroceryProduct 类型的对象。如果它不能,那么它会抛出一个错误。有关JSONDecoder 的更多信息,请参阅此well written answer
- 作为需要类型的替代解决方法,请参阅以下问题:Swift can't infer generic type when generic type is being passed through a parameter。接受的答案提供了一个有趣的选择。
有关内部结构及其工作原理的更多信息:
.类型
类、结构或枚举类型的元类型是
该类型后跟 .Type。协议类型的元类型——不是
在运行时符合协议的具体类型——是
该协议后跟 .Protocol。例如,元类型
class 类型 SomeClass 是 SomeClass.Type 和元类型
协议 SomeProtocol 是SomeProtocol.Protocol。
来自苹果:metaType Type
Under the hoodAnyClass是
typealias AnyClass = AnyObject.Type // which is why you see T.Type
基本上你在哪里看到AnyClass、Any.Type、AnyObject.Type,因为它需要一个类型。我们看到的一个非常常见的地方是当我们想要使用register func 为我们的tableView 注册一个类时。
func register(_ cellClass: Swift.AnyClass?, forCellReuseIdentifier identifier: String)
如果你对 'Swift.' 是什么感到困惑。然后执行上述操作,然后查看来自 here
的 cmets
上面也可以写成:
func register(_ cellClass: AnyObject.Type, forCellReuseIdentifier identifier: String)
.自己
您可以使用 postfix 自表达式将类型作为值访问。
例如, SomeClass.self 返回 SomeClass 本身,不是一个实例
SomeClass的。 SomeProtocol.self 返回 SomeProtocol 本身,不是
在运行时符合 SomeProtocol 的类型的实例。你
可以使用带有类型实例的type(of:) 表达式来访问
该实例的动态、运行时类型作为值,如下所示
示例显示:
来自苹果:metaType Type
游乐场代码:
简单示例
struct Something {
var x = 5
}
let a = Something()
type(of:a) == Something.self // true
困难的例子
class BaseClass {
class func printClassName() {
print("BaseClass")
}
}
class SubClass: BaseClass {
override class func printClassName() {
print("SubClass")
}
}
let someInstance: BaseClass = SubClass()
/* | |
compileTime Runtime
| |
To extract, use: .self type(of)
Check the runtime type of someInstance use `type(of:)`: */
print(type(of: someInstance) == SubClass.self) // True
print(type(of: someInstance) == BaseClass.self) // False
/* Check the compile time type of someInstance use `is`: */
print(someInstance is SubClass) // True
print(someInstance is BaseClass) // True
我强烈推荐阅读 Apple documentation on Types。另见here