【问题标题】:Passing Data Indirectly to an Unrelated NSViewController将数据间接传递给不相关的 NSViewController
【发布时间】:2019-06-13 22:42:20
【问题描述】:
  • 我是 macOS 开发的新手,我正在开发一个使用 Xcode 10 和 Swift 4.2 的 macOS 项目。
  • 该项目主要包含 3 个视图控制器。
  • 首先,ViewController将另外两个分开的主欢迎屏幕)有两个按钮可以分别调用另外两个。
  • 其次,MakeEntry 视图控制器使用由以下组成的表单类型结构创建 字符串数组 数据变量文本视图和保存按钮等,最后只是将所有输入数据保存到一个名为 carrierArray字符串数据变量数组
  • 第三,有一个拆分视图控制器,用于显示两个子视图控制器,即EntryList进入详情
  • EntryList(左窗格)包含一个表格视图来显示条目的标题,EntryDetail(右窗格)将包含标题条目的描述(有点像 macOS 的默认笔记应用)

  • 我想实现一个简单的功能,即能够访问读取 字符串数组名为的变量在 MakeEntry 视图控制器将其保存到在其自己的类文件中定义的 全局变量中时创建的carrierArray 但我想在任何地方访问该字符串数组并且以后的任何时候。

  • 不能使用委托和协议、闭包、segues 或情节提要标识符来携带该数据,因为我没有直接导航到拆分视图控制器,还因为我想要存储该数据 在拆分视图控制器的右窗格中显示之前进一步操作 (EntryDetail)
  • 我无法弄清楚是否可以使用 NSUserDefaults 或 CoreData 来实现此功能。
  • 因此,我在 Dictionary存储 字符串数组 后尝试使用通知中心 >notifDictionary 包含一个名为 carryData 的键,要存储为 数据对象通知中心并且经过一些研究和一些试验和错误,但没有任何运气,所有这些都导致无法在拆分视图控制器左窗格类文件中获取该数据,即 (EntryDetail)。李>
  • 代码片段如下,非常感谢您的帮助。

在 MakeEntry 视图控制器中:

 notifDictionary = ["carryData": carrierArray]

        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "dataCarrier") , object: nil, userInfo: notifDictionary)

在 EntryList 视图控制器中: (尝试一次使用两种类型的选择器方法,甚至一起使用它们,但都没有运气!请帮助!) 变量 datumDictdatumArray 以及 carrierArraynotifDictionary

的复制接收器
var datumDict: [String:[String]] = [:]
var datumArray: [String] = []


override func viewDidLoad() {
    super.viewDidLoad()



    NotificationCenter.default.addObserver(self, selector: #selector(self.getThatDict(_:)), name: NSNotification.Name(rawValue: "dataCarrier") , object: nil)

    NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "dataCarrier") , object: nil, queue: nil, using: catchNotification)

    //datumArray = datumDict["carryData"]!

}




 @objc func onNotification(notification:Notification)
    {
        print(notification.userInfo!)
    }

func catchNotification(notification: Notification) -> Void
{
    let theDict = notification.object as! NSDictionary
    datumDict = theDict as! [String: [String]]
    guard let theData = notification.userInfo!["carryData"] as? [String:[String]] else { return }
    datumDict = theData
}


@objc func getThatDict(_ notification: NSNotification)
{
    print(notification.userInfo ?? "")
    if let dict = notification.userInfo as NSDictionary?
    {
        if let thatDict = dict["carryData"] as? [String: [String]]
        {
            datumDict = thatDict
        }
    }
}

【问题讨论】:

    标签: swift macos cocoa nsnotificationcenter nsviewcontroller


    【解决方案1】:

    需要注意的是“应避免使用全局变量和单例”,听起来它们非常适合您尝试做的事情。随着您对 Cocoa 的熟悉程度越来越高,您可以采用更复杂的方法来实现这一点(依赖注入)。当您对 Cocoa 越来越熟悉时,请考虑这一点。

    创建一个简单的单例类型:

    // AppState.swift
    
    class AppState {
        // Basic singleton setup:
        static let shared = AppState()
        private init() {} // private prevents instantiating it elsewhere
    
        // Shared state:
        var carrierArray: [String] = []
    }
    

    从您的视图控制器访问它:

    // YourViewController.swift:
    
        @IBAction func doSomething(_ sender: Any) {
            AppState.shared.carrierArray = ...
        }
    

    如果您需要在此共享状态更改时更新其他视图控制器,通知是一个很好的工具。您可以在carrierArray 上使用didSet 来执行此操作,或者只是手动触发通知。

    【讨论】:

    • 在共享状态更改时手动触发通知和更新其他视图控制器的一点帮助或一些提示将得到确认和高度赞赏!这种使用共享状态变量的方法非常棒,我很喜欢!
    猜你喜欢
    • 1970-01-01
    • 2018-12-11
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    • 2018-02-14
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    相关资源
    最近更新 更多