如何观察全局变量的值以及如何在ViewController中进行更改

时间:2019-03-27 16:49:17

标签: swift

我在iOS应用中使用通用链接,并且可以将URL值成功存储为全局变量。这是在应用程序委托的早期完成的。从启动开始,以及从后台重新打开应用程序时,此方法都有效。

然后将该URL作为源URL传递到WKWebView。

问题是WKWebView的ViewController已经加载,并且直到我进行反复搜索才检测到新URL。

我编写了一段非常丑陋的代码,但是可以满足生产要求。它监视主线程中变量的变化,但是通过重复循环和1秒钟的睡眠来完成,以避免CPU过度运行。

当全局变量的值不等于默认值时,在视图控制器内进行排序的正确方法是什么?

我已经看过遗嘱了。但是由于我的变量是在视图控制器类之外定义的,所以我无法执行segue。

// home made loop to look for a change in universal link
    DispatchQueue.global().async {
     repeat
      {
       sleep(1) // save CPU
      }
     while universalOverrideURL == "none"
     DispatchQueue.main.sync {
     print("S E G U E  I S  N E E D E D !")
   }
}

我是否可以采用一种更好的方法来尊重CPU?

2 个答案:

答案 0 :(得分:1)

有很多方法可以解决此问题。 iOS的本机方式是使用NotificationCenter:

//Make your custom notification
extension Notification.Name {
    static let myCustomValueUpdated = Notification.Name("myCustomValueUpdated")
}

//Post the notification when you the value
NotificationCenter.default.post(Notification(name: .myCustomValueUpdated, object: nil, userInfo: ["value": someNewValue]))

//Subscribe everywhere that needs to be interested in UserDefaults changes
let token = NotificationCenter.default.addObserver(forName: .myCustomValueUpdated, object: nil, queue: .main) { notification in
    if let value = notification.userInfo["value"] {
        //Do stuff with new value here
    }
}

您还可以考虑提供一项服务,以将值包装为您要更改的值,然后使用观察者模式允许其他对象订阅该值的更改。我倾向于使用此解决方案,因为它具有1)可测试和可模拟,2)强类型化,3)将内容移出应用程序委托的功能,但是如果您对此不关心,则只需使用NotificationCenter,因为它的工作量最少以及众所周知的苹果图案。

答案 1 :(得分:0)

您可以使用委托来通知您的ViewController。

这是委托人的接口:

@protocol UniversalOverrideURLObserver

func onURLChanged(url: String) -> Void

@end

您的ViewController可以实现此接口:

class ViewController: UIViewController,  UniversalOverrideURLObserver {

}

然后,实例化ViewController的代码可以执行以下操作:

func addObserver(observer: UniversalOverrideURLObserver) -> Void {
    self.observer = observer
}

func funcWhereValueChanges() {
    // HERE your url changed    
    self.observer.onURLChanged(url: newURL)
}

func funcWhereViewControllerShown() {
    // HERE you are ready to present ViewController
    let vc = ViewController()
    self.addObserver(vc)
}