自定义初始化程序,为什么使用Date()而不是dateCreated



我正在学习如何初始化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
}
}

根据规则,创建实例时必须初始化所有属性。namevalueInDollarsserialNumber的默认值在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) {

只有nameserialNumbervalueInDollars。没有应该设置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)
)

最新更新