当我不使用Storyboard时,在所需的init中可以有fatalError吗?(编码器aDecoder:NSCoder)?

时间:2022-04-26 20:12:35

I have a ViewController, which need to be initialized with ViewModel: NSObject.

我有一个ViewController,需要使用ViewModel:NSObject进行初始化。

My implementation of ViewController is:

我对ViewController的实现是:

class ViewController: UIViewController {

    let viewModel: ViewModel

    init(withViewModel viewModel: ViewModel) {
        self.viewModel = viewModel
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

ViewModel has simple override init:

ViewModel具有简单的覆盖init:

class ViewModel: NSObject {

    override init() {
        super.init()
        // Some other logic
    }

}

I understand, that I need required init?(coder aDecoder: NSCoder) in ViewController implementation since it conforms NSCoding protocol. But I'm not sure if it is safe to have fatalError there.

我明白,我需要在ViewController实现中使用init?(coder aDecoder:NSCoder),因为它符合NSCoding协议。但我不确定在那里有fatalError是否安全。

When I change fatalError to super.init(coder: aDecoder) I receive

当我将fatalError更改为super.init(coder:aDecoder)时,我收到了

property 'self.viewModel' not initialized at super.init call

属性'self.viewModel'未在super.init调用中初始化

I don't want to make viewModel an optional variable, because in my App logic it can't be nil.

我不想让viewModel成为可选变量,因为在我的App逻辑中它不能是nil。

Also, when I change init?(coder... to

另外,当我改变init?(编码器......)

required init?(coder aDecoder: NSCoder) {
    self.viewModel = ViewModel()
    super.init(coder: aDecoder)
}

this also doesn't satisfy me, since viewModel isn't the only constant, which need to be implemented during initialization of ViewController.

这也不满足我,因为viewModel不是唯一的常量,需要在ViewController初始化期间实现。

So, my questions:

所以,我的问题:

  • Is it safe to have fatalError in this init method?
  • 在这个init方法中有fatalError是否安全?

  • I don't use Storyboards in my App (only for Launch Screen). Can I be sure, that this init?(coder... method won't run in any case?
  • 我不在我的应用程序中使用Storyboard(仅适用于启动屏幕)。我可以肯定,这个init?(编码器......方法无论如何都不会运行?

  • Or maybe there is an option to write it without fatalError?
  • 或者也许有一个选项来写它没有fatalError?

  • Or do I need a full implementation in it, because in some cases my App will use it?
  • 或者我需要一个完整的实现,因为在某些情况下我的应用程序将使用它?

Thanks for any help!

谢谢你的帮助!

2 个解决方案

#1


5  

Since you don't use storyboard you can disable your init, so you won't be able to use it in code:

由于您不使用故事板,因此可以禁用init,因此您将无法在代码中使用它:

@available(*, unavailable) required init?(coder aDecoder: NSCoder) {
    fatalError("disabled init")
}

#2


1  

Here you have a good startup with dependency injection as well, if you wish to make it easy to write tests for it later with mocked data.

如果您希望以后使用模拟数据轻松编写测试,那么在这里您也可以使用依赖注入进行良好的启动。

ViewController:

class ViewController: UIViewController {

    let viewModel = ViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()
        viewModel.runFunction()
    }
}

ViewModel:

class ViewModel: NSObject {

    var networkingService: NetworkingService?

    init(withNetworkingService networkingService: NetworkingService = null) {
        self.networkingService = networkingService
    }
}

#1


5  

Since you don't use storyboard you can disable your init, so you won't be able to use it in code:

由于您不使用故事板,因此可以禁用init,因此您将无法在代码中使用它:

@available(*, unavailable) required init?(coder aDecoder: NSCoder) {
    fatalError("disabled init")
}

#2


1  

Here you have a good startup with dependency injection as well, if you wish to make it easy to write tests for it later with mocked data.

如果您希望以后使用模拟数据轻松编写测试,那么在这里您也可以使用依赖注入进行良好的启动。

ViewController:

class ViewController: UIViewController {

    let viewModel = ViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()
        viewModel.runFunction()
    }
}

ViewModel:

class ViewModel: NSObject {

    var networkingService: NetworkingService?

    init(withNetworkingService networkingService: NetworkingService = null) {
        self.networkingService = networkingService
    }
}