视图控制器中的依赖注入

时间:2018-09-10 14:19:00

标签: ios swift dependency-injection

有人可以解释一下View Controller中的依赖项注入,我们如何摆脱可选项?我已经阅读了很多文章,但是不清楚。将数据从一个VC传递到另一个VC是一种好方法吗?

class SecondVC: UIViewController {
    var number: [String]?

    override func viewDidLoad() {
        super.viewDidLoad()

        self.printNumbers()
    }

    func printNumbers() {
        guard let number = self.number else { return }

        print(number)
    }
}

//+++++++ In First View Controller +++++++++++++++++

@IBAction func pushToSecondVC(_ sender: UIButton) {
    let secondViewController = self.storyboard.instantiateViewControllerWithIdentifier("SecondVC") as SecondVC
    secondViewController.number = self.numbers
    self.navigationController.pushViewController(secondViewController, animated: true)
}

4 个答案:

答案 0 :(得分:0)

在您的示例中,如果您只是想摆脱可选项,请将clickButton: function(button,callback) { let el; el=element(by.css(button)); el.click().then(function () { callback(); }); }, 替换为var number: [String]?。这将创建一个空数组。

当您必须访问此属性时,您不再需要打开它。

答案 1 :(得分:0)

您可以摆脱它们,但是随后您需要从代码而不是故事板中启动它们。 如果您想使用类似的启动方法,我认为您最好的方法是更改​​可选参数以强制展开类型并具有某种静态启动器功能,如下所示:

final class ViewController: UIViewController {
    var number: [String]!

    static func initiateFromStoryboard(with number: [String]) -> ViewController {
        let viewController = UIStoryBoard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SecondVC") as! ViewController
        viewController.number = number
        return viewController
    }
}

//// Use it like:
...
let vc = ViewController.initiateFromStoryboard(with: ["1","2"])
navigationController?.push(vc) 

Ofc。缺点是您需要在使用之前始终注意number属性的设置,否则代码将崩溃。

答案 2 :(得分:0)

如果要摆脱可选选项,您有几种选择:

  1. 不要将它们设为可选,并为其提供默认值。当然,只有在存在合理的默认值的情况下,这才有效。
  2. 使它们隐式展开。它们仍然是可选的,但是您不必处理它们的包装。仅当您确定知道呈现视图控制器为其提供值时,此方法才起作用。
  3. 使用自定义初始化程序,该自定义初始化程序在视图控制器初始化时采用一个值并分配属性。很好,也很干净,但不适用于情节提要。

答案 3 :(得分:0)

这里的其他建议建议为var设置初始值。尽管这意味着较少的可选项,但是这里的问题是设置var很容易忘记,这可能会导致难以诊断问题。

我赞成private隐式展开的可选内容,例如

private var number: [String]!
private (set) var someBool: Bool! // private (set) makes it visible but not setable

,然后在每个视图控制器(或从笔尖的故事板上实例化的任何对象)上的configure函数,例如

configure(number: [String], someBool: Bool) {
    self.number = number
    self.someBool = someBool
}

未包装的可选选项如果未设置将在使用时崩溃,并且由于它们是私有的,因此不能从类本身之外意外地更新它们。