使用观察者模式设置委托时出现问题
Having issues setting delegate with Observer Pattern
我正在尝试实现观察者模式,但遇到了一些困难,因为我的委托似乎没有正确设置。
在我的 Main.storyboard 中,我有一个带有容器视图的 ViewController。我还有一个输入框,我可以在其中从数字键盘捕获数字。
这是我的故事板:
我正在尝试使用如下所示的协议实现我自己的观察者模式:
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
}
}
我的观察ViewController:
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
}
}
这是我的控制台打印的内容:
发生了什么事
如您所见,当我的 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
。
问题
如何正确设置我的委托?
您正在调用情节提要来实例化一个视图控制器并将其设置为观察者,但是实例化该视图控制器的一个新实例并不意味着它引用了一个单独的 "view controller" 在情节提要中。 ObservingViewController 需要另一种方式来引用已经创建的 ViewController。
所以 确实强化了我的怀疑,这帮助我找到了将我的委托正确分配给我的视图控制器的解决方案。
在我的 ObservingViewController
中,我只需要将 viewDidLoad 中的代码替换为以下代码:
override func viewDidLoad() {
let app = UIApplication.sharedApplication().delegate as! AppDelegate
let vc = app.window?.rootViewController as! ViewController
vc.observer = self
}
我现在不是创建视图控制器的新实例,而是获取实际的视图控制器。
我正在尝试实现观察者模式,但遇到了一些困难,因为我的委托似乎没有正确设置。
在我的 Main.storyboard 中,我有一个带有容器视图的 ViewController。我还有一个输入框,我可以在其中从数字键盘捕获数字。
这是我的故事板:
我正在尝试使用如下所示的协议实现我自己的观察者模式:
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
}
}
我的观察ViewController:
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
}
}
这是我的控制台打印的内容:
发生了什么事
如您所见,当我的 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
。
问题
如何正确设置我的委托?
您正在调用情节提要来实例化一个视图控制器并将其设置为观察者,但是实例化该视图控制器的一个新实例并不意味着它引用了一个单独的 "view controller" 在情节提要中。 ObservingViewController 需要另一种方式来引用已经创建的 ViewController。
所以
在我的 ObservingViewController
中,我只需要将 viewDidLoad 中的代码替换为以下代码:
override func viewDidLoad() {
let app = UIApplication.sharedApplication().delegate as! AppDelegate
let vc = app.window?.rootViewController as! ViewController
vc.observer = self
}
我现在不是创建视图控制器的新实例,而是获取实际的视图控制器。