我正在使用 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/
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
似乎无法为此找到有效的答案。我正在阅读Rails教程的第10章第10.1.2节,但似乎无法使邮件程序预览正常工作。我发现处理错误的所有答案都与教程的不同部分相关,我假设我犯的错误正盯着我的脸。我已经完成并将教程中的代码复制/粘贴到相关文件中,但到目前为止,我还看不出我输入的内容与教程中的内容有什么区别。到目前为止,建议是在函数定义中添加或删除参数user,但这并没有解决问题。触发错误的url是http://localhost:3000/rails/mailers/user_mailer/account_activation.http://localhost:3000/rails/mai
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行
所以我开始关注ruby,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出
可能已经问过了,但我找不到它。这里有2个常见的情况(对我来说,在编程Rails时......)用ruby编写是令人沮丧的:"astring".match(/abc(.+)abc/)[1]在这种情况下,我得到一个错误,因为字符串不匹配,因此在nil上调用[]运算符。我想找到的是比以下内容更好的替代方法:temp="astring".match(/abc(.+)abc/);temp.nil??nil:temp[1]简而言之,如果不匹配,则简单地返回nil而不会出错第二种情况是这样的:var=something.very.long.and.tedious.to.writevar=some