我是macOS开发的新手,我正在使用Xcode 10和Swift 4.2为macOS开发一个项目。
该项目主要包含3个视图控制器。
首先,ViewController(将另外两个分开的主欢迎屏幕)有两个按钮分别调用另外两个按钮。
其次,MakeEntry视图控制器使用由文本视图和save按钮等组成的表单类型结构创建一个字符串数据变量数组,最后将所有输入数据保存到一个名为carrierray的字符串数据变量数组中
第三,有一个分割视图控制器,用于显示两个子视图控制器EntryList和EntryDetail
EntryList(左窗格)包含一个显示条目标题的表视图,EntryDetail(右窗格)将包含标题条目的描述(有点像macOS的默认notes应用程序)
我想实现一个简单的功能,即能够访问或读取名为carrierray的字符串变量数组,该数组是在MakeEntry视图控制器将其保存到自己的类文件中定义的全局变量中时创建的,但我想在以后的任何时间任何地点访问该字符串数组。
我不能使用委托和协议、闭包、segue或脚本标识符来携带数据,因为我没有直接导航到Split View控制器,也因为我想存储这些数据
在拆分视图控制器(EntryDetail)的右窗格中显示之前进一步操作它。
我无法确定如何使用NSUserDefaults或CoreData实现此功能。
因此,在将字符串数组存储在字典(即notifDictionary)中(notifDictionary)之后,我尝试使用通知中心,该字典包含一个称为carryData的键,将其存储为通知中心的数据对象,并进行了一些研究和一些尝试和错误,但没有任何运气,所有这些都导致无法在拆分视图中获取该数据控制器左窗格类文件即(EntryDetail)。
代码片段如下,非常感谢您的帮助。
在MakeEntry视图控制器中:

 notifDictionary = ["carryData": carrierArray]

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

在EntryList视图控制器中:
(尝试一次一个地使用这两种选择器方法,甚至一起使用,但都没有成功!请帮忙!)
变量datumDict和datumArray,而不是carrierray和notifDictionary的复制接收器
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
        }
    }
}

最佳答案

有一点需要注意的是“应该避免全球性和单一性”,听起来它们很适合你所要做的事情。当您在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 = ...
    }

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

关于swift - 将数据间接传递给不相关的NSViewController,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54274771/

10-13 07:29
查看更多