【问题标题】:Passing data between View Controllers with NSNotificationCenter使用 NSNotificationCenter 在视图控制器之间传递数据
【发布时间】:2015-12-15 08:22:16
【问题描述】:

每个人。我编写了这段代码来在 VC 之间传递数据,但我不确定为什么它不起作用。

这是 ViewController1 中的代码:-

import UIKit
import Foundation

let foodDict: [String:String] = [
    "Orange": "Fruit",
    "Carrot": "Vegetable",
    "Pear": "Fruit",
    "Spinach": "Vegetable"
]

class ViewController1: UIViewController {

     override func viewDidLoad() {
         super.viewDidLoad()

         NSNotificationCenter.defaultCenter().postNotificationName("SEND_STRING", object: nil, userInfo: foodDict)

     }
 }

在 ViewController2 中:-

import UIKit
import Foundation

class ViewController2: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        NSNotificationCenter.defaultCenter().addObserver(self, selector: "printStringDict:", name: "SEND_STRING", object: nil)
    }

    func printStringDict(notification: NSNotification) {

        print("Got the notification...")
        let foodDictFromVC1 = notification.userInfo as! [String:String]
        print(foodDictFromVC1)
    }

}

VC2 没有得到字典(因为没有打印)。有人可以帮忙吗?提前致谢。

【问题讨论】:

  • 控制台中是否正在打印“收到通知...”?在我看来,VC2 没有在 VC1 之前加载,因此观察者还不存在。
  • 在调用ViewController1viewDidLoad函数时是否存在ViewController2的实例?只有在通知时存在的观察者才会被告知通知。
  • 顺便说一句 - 这不是一个真正的好方法。但是如果不知道两个视图控制器之间的关系,就很难确定。
  • 没有任何东西被打印到控制台。 VC1 有一个按钮,点击后会连接到 VC2。
  • 您应该通过 segue 而不是通知传递数据。通知通常用于让多个对象或它们之间没有链接的对象存在已更改的状态。您编写的用于发送和观察通知的代码是正确的。它只是它出错的顺序。

标签: ios swift nsnotificationcenter nsnotification


【解决方案1】:

所以问题是您发布了通知,但您的 VC2 尚未初始化,因此没有人可以看到您在 VC1 中加载的这篇帖子。最好使用 prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 函数在两个与 segue 连接的 ViewController 之间进行通信,例如:

import UIKit
import Foundation



class ViewController1: UIViewController {

    let foodDict: [String:String] = [
        "Orange": "Fruit",
        "Carrot": "Vegetable",
        "Pear": "Fruit",
        "Spinach": "Vegetable"
    ]
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "segueIdentifierSetInStoryboard" {
            if let destinationVC = segue.destinationViewController as? ViewController2{
                destinationVC.printStringDict(foodDict)
            }
        }
    }
}

class ViewController2: UIViewController {       
    func printStringDict(fooDict:[String:String]) {
        print(fooDict)
    }
}

【讨论】:

  • 您也可以使用单例,它可以让您将 foodDict 保存在一个地方,并且任何 ViewController 都可以访问它。
  • 不,不要使用单例。
  • 感谢您的回复,卡米尔。我知道 segue 方法,但我想看看是否有办法对通知做同样的事情。这似乎是不可能的。
  • @Wertever 如果您想通过通知获得答案,为什么要接受这个答案?它可以通过通知轻松完成。您只需要在观察者设置好接收通知后发布通知。
  • @Wertever 是的,你可以,但通知不是两个对象之间通信的方式。当您实际上不知道何时触发您的操作时,最好使用通知。即使您有一对多对象的通信,我认为最好使用观察设计模式,因为通知会降低您的代码可读性并且更难调试。
【解决方案2】:

如果我理解: ViewController1 -> ViewController2

在这种情况下,您的代码将永远无法工作,因为在 ViewController1 中您发布了一个通知,但没有任何东西在监听您的通知,因为 ViewController2 尚未创建!

在 ViewController2 中,您添加了一个观察者,用于侦听任何符合名称“SEND_STRING”的通知。要使通知生效,您必须在 ViewController1 上添加一个观察者,然后在 ViewController2 上触发一个发布通知! => ViewController1 将收到通知!

【讨论】:

    猜你喜欢
    • 2011-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多