【问题标题】:How do I initialize a class over the course of several view controllers如何在多个视图控制器的过程中初始化一个类
【发布时间】:2021-05-29 01:49:36
【问题描述】:

我有一个Event 类,其中包含DateTimeActivity 等变量。用户可以使用一系列视图控制器创建一个Event,让用户构建它一次可变,有点像演练。我的问题是为了在第一个屏幕上初始化 Event,我使用了一个空的初始化程序,并且所有实例变量默认情况下都是可选的。当用户浏览屏幕时,它们会被相应地设置。随着时间的推移,我将如何正确初始化这个类?对所有变量使用可选项似乎不合适。

我想像这样在第一个屏幕上初始化Event

var event = Event()

并一一设置它的实例变量,而不是它们都是可选的。

【问题讨论】:

  • "我想初始化..." 不。你不能随着时间的推移初始化一个类。您可以随着时间的推移设置实例的属性。既然如此,你正在做的似乎很好。别担心,开心就好。
  • 但是,您也可以继续调用生成器,该生成器仅在提供了所有需要的信息后才创建完整的事件。
  • @matt 这样的构建器功能如何工作?它如何在每次通话中添加到相同的事件中?或者变量仍然必须是可选的?
  • Builder 的变量是什么无关紧要,因为它们是私有的。它只是函数:输入函数,客户端可以提供信息,输出函数,生成器可以提供完整的事件。关键是,在这个模型上,Event 不需要任何 Optional 属性,因为 Builder 在获得所有信息之前不会实例化它。

标签: swift xcode class optional


【解决方案1】:

你不能随着时间的推移初始化一个类。您可以随着时间的推移设置实例的属性。既然如此,你正在做的似乎很好。 但是,或者您可以继续调用构建器,该构建器仅在提供了所有需要的信息时才创建完全形成的事件。想象一下这样的架构(在您的操场上尝试一下):

class Event : CustomStringConvertible {
    let fee : String
    let fi : String
    let fo : String
    let fum : String
    init(fee:String, fi:String, fo:String, fum:String) {
        self.fee = fee; self.fi = fi; self.fo = fo; self.fum = fum
    }
    var description : String {
        "Event: \(fee) \(fi) \(fo) \(fum)"
    }
}

class EventBuilder {
    private var fee : String?
    private var fi : String?
    private var fo : String?
    private var fum : String?
    private var event : Event?
    private func makeEventIfPossible() {
        guard event == nil else {return}
        if let fee = fee,
           let fi = fi,
           let fo = fo,
           let fum = fum {
            print("making event")
            self.event = Event(fee: fee, fi: fi, fo: fo, fum: fum)
        }
    }
    func takeFee(_ fee:String) {
        self.fee = fee
        makeEventIfPossible()
    }
    func takeFi(_ fi:String) {
        self.fi = fi
        makeEventIfPossible()
    }
    func takeFo(_ fo:String) {
        self.fo = fo
        makeEventIfPossible()
    }
    func takeFum(_ fum:String) {
        self.fum = fum
        makeEventIfPossible()
    }
    func giveEvent() -> Event? {
        self.event
    }
}

let b = EventBuilder()
b.takeFee("Fee")
b.takeFi("Fi")
b.takeFo("Fo")
b.takeFum("Fum")
if let event = b.giveEvent() {
    print(event) // and away we go
}

您可以传递 EventBuilder,不同的对象可以调用不同的take 方法,并且在提供所有信息并创建事件之前,没有人可以使用giveEvent 获取事件。如您所见,Event 只创建一次,它的所有属性都不是可选的。构建器将整个创建过程隐藏在函数表示之后(因此得名)。

我可以想象进一步的改进,比如你可以创建 take 方法 throws 方法,如果该值已经设置,他们将拒绝接受一个值,等等。另外我认为您可能会以某种方式使用键路径来使代码更整洁/更小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    相关资源
    最近更新 更多