在swift3中使用方法而不是块初始化惰性变量 在swift3文件中。建议通过以下两种方式使用lazy: 1.直接初始化 2.带块初始化

在swift3中使用方法而不是块初始化惰性变量 在swift3文件中。建议通过以下两种方式使用lazy: 1.直接初始化 2.带块初始化,swift,lazy-loading,lazy-evaluation,lazy-initialization,Swift,Lazy Loading,Lazy Evaluation,Lazy Initialization,如果我想用一些默认值惰性地初始化某个变量。我只能走第二条路。但这似乎太笨拙了。 因此,我使用以下方法初始化lazy变量。它运行正常。但这真的可以吗?我需要一些帮助 class SomeViewController: UIViewController { lazy var someViews: UILabel = self.initSomeViews() override func viewDidLoad() { print(self.someViews)

如果我想用一些默认值惰性地初始化某个变量。我只能走第二条路。但这似乎太笨拙了。 因此,我使用以下方法初始化lazy变量。它运行正常。但这真的可以吗?我需要一些帮助

class SomeViewController: UIViewController {
    lazy var someViews: UILabel = self.initSomeViews()

    override func viewDidLoad() {
        print(self.someViews)
    }
}

fileprivate extension SomeViewController {

    func initSomeViews() -> UILabel! {
        let overlayView = UILabel()
        overlayView.backgroundColor = UIColor.white.withAlphaComponent(0.90)
        overlayView.font = UIFont.boldSystemFont(ofSize: YFCalendarOverlaySize)
        overlayView.alpha = 0.0
        overlayView.textAlignment = .center
        overlayView.translatesAutoresizingMaskIntoConstraints = false
        return overlayView
    }
}

可以,但您的
initSomeViews()
与使用块的概念相同。您可以直接为其分配clouser,也可以为其分配方法

注:

如果在viewDidLoad:中使用lazy属性,则没有 需要声明它是懒惰的

-它们只初始化一次,不再计算,也就是说,它们不会动态计算


我建议不要使用闭包变量:

lazy var overlayView: UILabel = { [unowned self] in
    let overlayView = UILabel()
    // ...
    return UILabel()
}()
为什么?

我自己做了一个小调查。请按照以下步骤阅读详细说明

正确使用功能:

class SomeViewController: UIViewController {

    lazy var label: UILabel = self.getLabel()
}

fileprivate extension SomeViewController {

    func getLabel() -> UILabel {
        return UILabel()
    }
}
出于安全和风格的考虑(我可能会被否决……),我喜欢使用隐式展开选项:

private var someViews: UILabel!

override func viewDidLoad() {
    self.someViews = createSomeViews()
}

private func createSomeViews() -> UILabel { ... }
安全性。在
viewDidLoad
方法上立即运行初始化,可以在整个视图控制器设置中获得一个很好的确定性代码路径。相反,使用
lazy
可能会有多个触发var创建的代码路径,从而可能隐藏潜在的讨厌的bug(例如,在视图中考虑交叉依赖关系等)

风格。我能说什么?它只是在眼睛里看起来更好:)


但是,如果您的var初始化包含一些您希望尽可能推迟的代价高昂的计算,那么
lazy
就是最好的选择

非常感谢。但是你想分享你的答案链接吗?你的答案是swift文件的一部分吗?我不知道为什么会有人投票反对你。这与我用于依赖已加载的用户界面的变量的模式相同。您可以懒洋洋地初始化它们,并希望它们在视图加载之前不会被引用,但是,正如您所说,它可能会引入令人讨厌的非确定性错误。感谢@JeremyP:)的反馈
lazy private var someViews:UILabel={return self.createSomeViews()}()
或类似的东西怎么样?在
viewdiload()
(想想
init(with:)
)之前可以引用一个隐式展开的可选项会有潜在的危险,不是吗?我读了你的文章,这对解决这个问题很有好处。所以在这种情况下,是否有必要在my
“InitSomeView”
函数中的“中使用“
”[unowned self]?@JasonYu unowned不是必需的。我已经用正确用法更新了帖子示例如果我使用self.title在
getLabel()
方法中设置默认文本,那么是否需要unowned?如果不是,哪里需要无主?无主不需要。但这是一个关于无主的非常有趣的问题。这个问题需要对捕获列表等有更深入的理解。你应该发布一些关于无主/弱等的其他问题“(…)我只能使用第二种方式。但这似乎太笨拙了。”,不,实际上这是一种完全合理的方式,而“因此,我使用以下方法初始化lazy变量。它运行正常。但这真的可以吗?”,恐怕这是一个笨拙的解决方案:(
class SomeViewController: UIViewController {

    lazy var label: UILabel = self.getLabel()
}

fileprivate extension SomeViewController {

    func getLabel() -> UILabel {
        return UILabel()
    }
}
private var someViews: UILabel!

override func viewDidLoad() {
    self.someViews = createSomeViews()
}

private func createSomeViews() -> UILabel { ... }