在使用Observer Pattern设置委托时遇到问题

时间:2016-01-09 23:47:02

标签: swift delegates protocols observer-pattern

我正在尝试实现观察者模式,因为我的代表似乎没有正确设置,所以我遇到了一些困难。

在我的Main.storyboard中,我有一个带容器视图的ViewController。我还有一个输入框,我从数字键盘上捕捉数字。

这是我的故事板:

enter image description here

我正在尝试使用如下所示的协议实现我自己的Observer模式:

protocol PropertyObserverDelegate {
    func willChangePropertyValue(newPropertyValue:Int)
    func didChangePropertyValue(oldPropertyValue:Int)
}

我的主要ViewController.swift

class ViewController: UIViewController {

    @IBOutlet weak var numberField: UITextField!
    // observer placeholder to be initialized in implementing controller
    var observer : PropertyObserverDelegate?
    var enteredNumber: Int = 0 {

        willSet(newValue) {
            print("//Two: willSet \(observer)") // nil !
            observer?.willChangePropertyValue(5) // hard coded value for testing
        }
        didSet {
            print("//Three: didSet")
            observer?.didChangePropertyValue(5) // hard coded value for testing
        }
    }

    @IBAction func numbersEntered(sender: UITextField) {
        guard let inputString = numberField.text else {
            return
        }
        guard let number : Int = Int(inputString) else {
            return
        }
        print("//One: \(number)")
        self.enteredNumber = number // fires my property observer
    }
}

My ObservingViewController:

class ObservingViewController: UIViewController, PropertyObserverDelegate {
    // never fires!
    func willChangePropertyValue(newPropertyValue: Int) {
        print("//four")
        print(newPropertyValue)
    }
    // never fires!
    func didChangePropertyValue(oldPropertyValue: Int) {
        print("//five")
        print(oldPropertyValue)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        print("view loads")
        // attempting to set my delegate
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let pvc = mainStoryboard.instantiateViewControllerWithIdentifier("ViewController") as! ViewController
        print("//six \(pvc)")
        pvc.observer = self
    }
}

这是我的控制台打印的内容:

enter image description here

发生了什么

正如您可以看到我的willSet触发时,我的观察者是nil,表示我未能在ObservingViewController中设置我的委托。我以为我使用这些行设置了我的代表:

    let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let pvc = mainStoryboard.instantiateViewControllerWithIdentifier("ViewController") as! ViewController
    print("//six \(pvc)")
    pvc.observer = self

但是,如果我的代表回来nil,我必须正确设置我的代表。

问题

如何正确设置我的代理?

2 个答案:

答案 0 :(得分:1)

您正在调用故事板来实例化视图控制器并将其设置为观察者,但是实例化该视图控制器的新实例,并不意味着它引用了单个“视图控制器”,即在故事板中。 ObservingViewController需要另一种方法来引用已经创建的ViewController。

答案 1 :(得分:0)

所以@Chris确实增加了我的怀疑,这帮助我找到了一个解决方案,可以正确地将我的代表分配给我的视图控制器。

在我的ObservingViewController中,我只需要使用以下内容替换viewDidLoad中的代码:

override func viewDidLoad() {
    let app = UIApplication.sharedApplication().delegate as! AppDelegate
    let vc = app.window?.rootViewController as! ViewController
    vc.observer = self
}

我现在正在使用实际的视图控制器,而不是创建视图控制器的新实例。