gpt4 book ai didi

Swift OSX - 委托(delegate)协议(protocol)函数返回 nil,在展开文本字段值时崩溃

转载 作者:搜寻专家 更新时间:2023-10-31 22:56:50 24 4
gpt4 key购买 nike

我正在使用 Swift 开发一个 OSX 应用程序,它使用一个 NSSplitView,它包含两个 View Controller :“TableViewController”和“EntryViewController”。我正在使用委托(delegate),以便在单击时将自定义 NSObject(“Entry”)从 TableViewController 传输到 SplitViewController,然后返回到 EntryViewController。

我的问题是这样的:当 EntryViewController 接收到 Entry 对象时,任何将其属性分配给文本字段值的尝试都会导致意外找到 nil 类型错误,不要介意 IBOutlets 已正确链接,并且它可以同时打印 Entry.property 文本字段字符串值(前提是它在不同的、不相关的函数中)。

我已经尝试了很多安排来解决这个问题,这就是为什么当前的配置可能有点过于复杂。直接从 Table VC 到 Entry VC 的委托(delegate)关系导致了同样的问题。

即使在调用委托(delegate)之前 View 已经加载,IBOutlets 是否有某种方式没有连接?我已经阅读了很多关于委托(delegate)的很多文章——主要是针对 iOS 的——但似乎无法找到问题的根源。我将是第一个承认我对 Swift 的掌握有点零碎的人,所以我愿意接受这样一种可能性,即我正在尝试做的只是糟糕的/hacky 编码,我应该尝试一些完全不同的东西。

感谢您的帮助!

表格 View Controller :

protocol SplitViewSelectionDelegate: class {
func sendSelection(_ entrySelection: NSObject)
}

class TableViewController: NSViewController {

@IBOutlet weak var searchField: NSSearchField!
@IBOutlet var tableArrayController: NSArrayController!
@IBOutlet weak var tableView: NSTableView!

var sendDelegate: SplitViewSelectionDelegate?

dynamic var dataArray = [Entry]()

// load array from .plist array of dictionaries

func getItems(){
let home = FileManager.default.homeDirectoryForCurrentUser
let path = "Documents/resources.plist"
let urlUse = home.appendingPathComponent(path)

let referenceArray = NSArray(contentsOf: urlUse)
dataArray = [Entry]()

for item in referenceArray! {
let headwordValue = (item as AnyObject).value(forKey: "headword") as! String
let defValue = (item as AnyObject).value(forKey: "definition") as! String
let notesValue = (item as AnyObject).value(forKey: "notes") as! String

dataArray.append(Entry(headword: headwordValue, definition: defValue, notes: notesValue))
}
}

override func viewDidLoad() {
super.viewDidLoad()
self.sendDelegate = SplitViewController()
getItems()
print("TVC loaded")
// Do any additional setup after loading the view.
}

// send selection forward to entryviewcontroller

@IBAction func tableViewSelection(_ sender: Any) {

let index = tableArrayController.selectionIndex
let array = tableArrayController.arrangedObjects as! Array<Any>
let obj: Entry
let arraySize = array.count
if index <= arraySize {
obj = array[index] as! Entry
print(index)
print(obj)
sendDelegate?.sendSelection(obj)
}
else {
print("index unassigned")
}
}

}

Split View Controller :

protocol EntryViewSelectionDelegate: class {
func sendSecondSelection(_ entrySelection: NSObject)
}

class SplitViewController: NSSplitViewController, SplitViewSelectionDelegate {

var delegate: EntryViewSelectionDelegate?
@IBOutlet weak var mySplitView: NSSplitView!

var leftPane: NSViewController?
var contentView: NSViewController?

var entrySelectionObject: NSObject!

override func viewDidLoad() {

super.viewDidLoad()

// assign tableview and entryview as child view controllers
let story = self.storyboard

leftPane = story?.instantiateController(withIdentifier: "TableViewController") as! TableViewController?
contentView = story?.instantiateController(withIdentifier: "EntryViewController") as! EntryViewController?

self.addChildViewController(leftPane!)
self.addChildViewController(contentView!)

print("SVC loaded")
}

func sendSelection(_ entrySelection: NSObject) {
self.delegate = EntryViewController() //if this goes in viewDidLoad, then delegate is never called/assigned
entrySelectionObject = entrySelection
print("SVC:", entrySelectionObject!)
let obj = entrySelectionObject!
delegate?.sendSecondSelection(obj)
}

}

最后,EntryViewController:

class EntryViewController: NSViewController, EntryViewSelectionDelegate {

@IBOutlet weak var definitionField: NSTextField!
@IBOutlet weak var notesField: NSTextField!
@IBOutlet weak var entryField: NSTextField!

var entryObject: Entry!

override func viewDidLoad() {
super.viewDidLoad()
print("EVC loaded")
}

func sendSecondSelection(_ entrySelection: NSObject) {
self.entryObject = entrySelection as! Entry
print("EVC:", entryObject)
print(entryObject.headword)
// The Error gets thrown here:
entryField.stringValue = entryObject.headword
}

}

最佳答案

您不需要委托(delegate)/协议(protocol),因为有对 EntryViewController 的引用(contentView)——顺便说一下,使用 EntryViewController() 创建的实例 不是 viewDidLoad 中的实例化实例。

只需使用contentView 引用:

func sendSelection(_ entrySelection: NSObject) {
contentView?.sendSecondSelection(entrySelection)
}

关于Swift OSX - 委托(delegate)协议(protocol)函数返回 nil,在展开文本字段值时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44975390/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com