我正在学习如何初始化UITableView和UITableViewController主题的类。为什么在下面的代码中我们使用Date((而不是dateCreated?非常感谢。
class Item {
var name: String
var valueInDollars: Int
var serialNumber: String?
let dateCreated: Date
init(name: String, serialNumber: String?, valueInDollars: Int) {
self.name = name
self.valueInDollars = valueInDollars
self.serialNumber = serialNumber
self.dateCreated = Date()
}
}
在您的示例中,dateCreated
属性实际上应该是常量。该值是在创建实例时指定的,永远不会修改。
所以更实用的方法是
class Item {
var name: String
var serialNumber: String?
var valueInDollars: Int
let dateCreated = Date()
init(name: String, serialNumber: String?, valueInDollars: Int) {
self.name = name
self.serialNumber = serialNumber
self.valueInDollars = valueInDollars
}
}
根据规则,创建实例时必须初始化所有属性。name
、valueInDollars
和serialNumber
的默认值在init
方法中分配,dateCreated
直接初始化。
在大多数情况下,struct
就足够了,init
方法可以省略
struct Item {
var name: String
var serialNumber: String?
var valueInDollars: Int
let dateCreated = Date()
}
如果其他结构成员也是常量,请将var
替换为let
。
您有以下属性:
self.name
self.valueInDollars
self.serialNumber
self.dateCreated
这些是在Item
类中声明的,如下所示:
class Item {
/// the following 4 properties
var name: String
var valueInDollars: Int
var serialNumber: String?
var dateCreated: Date
您的初始值设定项,即…
init(name: String, serialNumber: String?, valueInDollars: Int) {
目的是初始化所有这4个属性。
在你的初始化器中,这正是你正在做的:
self.name = name /// set self.name to name
self.valueInDollars = valueInDollars /// set self.valueInDollars to valueInDollars
self.serialNumber = serialNumber /// set self.serialNumber to serialNumber
self.dateCreated = Date() /// /// set self.name to Date()
注意self.
这是因为初始化器的参数标签与属性的名称相同。
那么,为什么最后一个属性self.dateCreated
被分配给Date()
呢?
再次查看初始化器的参数标签:
init(name: String, serialNumber: String?, valueInDollars: Int) {
只有name
、serialNumber
和valueInDollars
。没有应该设置self.dateCreated
的参数标签,所以您只创建了一个新的Date()
。
但是,如果您愿意,可以添加一个:
init(name: String, serialNumber: String?, valueInDollars: Int, someDateCreated: Date) {
然后将self.dateCreated
设置为someDateCreated
:
self.name = name /// set self.name to name
self.valueInDollars = valueInDollars /// set self.valueInDollars to valueInDollars
self.serialNumber = serialNumber /// set self.serialNumber to serialNumber
self.dateCreated = someDateCreated /// set self.name to someDateCreated
参数标签的名称不需要与属性的名称匹配,如someDateCreated
所示。要进行区分,请使用self.
TL;DR
编译器并不关心如何初始化属性。它唯一关心的是所有它们都已初始化。
例如,您可以这样做:
init() { /// no argument labels
self.name = "Some random name"
self.valueInDollars = 1234
self.serialNumber = "ABCDEFG"
self.dateCreated = Date()
}
或者这个:
init(name: String, serialNumber: String?) {
self.name = name /// set self.name to name
self.valueInDollars = 1234
self.serialNumber = serialNumber /// set self.serialNumber to serialNumber
self.dateCreated = Date()
}
如果你也可以像Leo Dabus建议的那样添加一个默认的= Date()
,这样当你创建Item
时,你就不需要提供它了
init(name: String, serialNumber: String?, valueInDollars: Int, someDateCreated: Date = Date()) {
self.name = name /// set self.name to name
self.valueInDollars = valueInDollars /// set self.valueInDollars to valueInDollars
self.serialNumber = serialNumber /// set self.serialNumber to serialNumber
self.dateCreated = someDateCreated /// set self.name to someDateCreated
}
/// --- usage ---
let someItem = Item(
name: "Apple",
serialNumber: "qwerty"
valueInDollars: 123
)
/// you could still pass in a date if you want
let someOtherItem = Item(
name: "Peach",
serialNumber: "asdfg"
valueInDollars: 99,
someDateCreated: Date(timeIntervalSinceReferenceDate: 12312313)
)