【问题标题】:How to Prevent variables to be initialized twice?如何防止变量被初始化两次?
【发布时间】:2019-06-04 22:18:55
【问题描述】:

我是 iOs 应用程序开发的新手,我想知道我的应用程序架构是否正确。我的应用程序中的一个错误让我相信我的一些变量被初始化了多次。

总结一下我的应用:2 个屏幕和 2 个视图,但只有一个控制器。根据当前视图,viewDidLoad 有不同的结果。 我不相信这是正确的做法。我想这个想法是为每个视图创建一个控制器?

但我主要关心的是:在我的 viewDidLoad 中,当主屏幕加载时,我设置了一个通知观察者。我相信(由于错误)每次屏幕加载时都会设置此观察者,然后多次调用。

我的问题是:把这个监听器放在哪里,有没有一个地方只在加载这个视图后才运行代码?应该通过将此侦听器放入变量来修复它?

AppDelegate 应用程序功能是否适合此类事情?

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    // Remove iphone sleep mode
    UIApplication.shared.isIdleTimerDisabled = true

    //Setup the external scanner object
    self.scanner.delegate = self
    self.scanner.connect()

    // Init the saved values
    let defaults = UserDefaults.standard

    // --------------- MAIN VIEW ---------------
    if(mainView != nil){

        // Add a notification receiver
        // Will receive results ### request
        NotificationCenter.default.addObserver(self, selector: #selector(mainTextNewLineNotification), name: Notification.Name(rawValue: "sendingToView"), object: nil)

        // Layout setup
        mainTextView.layer.cornerRadius = 6.0

        [...]
    }

    // --------------- SETTINGS VIEW ---------------
    if(settingsView != nil){

        //Fill the field with saved values
        inputHost.text = defaults.string(forKey: "hostname")
        inputPort.text = String(defaults.integer(forKey: "port"))
        if(defaults.string(forKey: "timeout") != nil){
            inputTimeout.text = defaults.string(forKey: "timeout")
        }
        if(UserDefaults().string(forKey: "confirmSwitch") == "On"){
            confirmSwitch.isOn = true
        } else {
            confirmSwitch.isOn = false
        }
    }
}

【问题讨论】:

  • 首先,如果您的应用程序很小,您可以从一个控制器控制两个视图,并且这些视图执行类似的操作,但这不是最佳实践。最好为每个视图创建控制器。您可以阅读有关 MVC 架构的信息,这对初学者来说很容易。正如@Dharmesh 所说,当 mainView 消失时删除通知观察者。如果你不移除观察者,它会调用多次。

标签: ios swift xcode architecture


【解决方案1】:
  1. 在您的情况下,您不需要关心 removeObserver 逻辑(因为您使用 -selector 的简单订阅,而不是 -block)。来自苹果doc: 如果您的应用面向 iOS 9.0 及更高版本或 macOS 10.11 及更高版本,则无需在其 dealloc(deinit) 方法中取消注册观察者。

  2. 每次初始化 UIViewController 的实例时,如果系统加载它的视图 viewDidLoad 将被调用。 viewDidLoadUIViewController 生命周期中被调用一次。所以你的订阅逻辑是正确的。

我不知道您的应用程序的整个逻辑,所以很难知道您的错误的原因是什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    • 2012-06-14
    • 1970-01-01
    • 2015-08-14
    • 2021-10-28
    相关资源
    最近更新 更多