如何连接 NSTableView/Table View 以避免运行时错误“无法连接操作,目标类 NSObject 不响应”)
Posted
技术标签:
【中文标题】如何连接 NSTableView/Table View 以避免运行时错误“无法连接操作,目标类 NSObject 不响应”)【英文标题】:How to wire-connect NSTableView/Table View to avoid runtime error "Could not connect action, target class NSObject does not respond to") 【发布时间】:2019-03-26 07:24:59 【问题描述】:在基于视图的单列 NSTableView 中,在其表格单元格视图中包含默认 NSTextField,我试图通过将 .xib 的 Interface Builder 视图中的 NSTextField 的操作连接到窗口的 ViewController 中的方法。但是在运行时(在窗口初始化期间)我得到“无法连接操作,目标类 NSObject 不响应 -textCellChanged”。我不明白哪个 NSObject 被错误地定位,并且我在窗口中有许多其他 NSView 正确连接到同一个 WindowController 中的其他插座和操作。
我看到其他各种具有类似症状的帖子,通常也在 NSTableView 的上下文中,并且在我的上下文中探索了这些其他问题的解决方案或部分解决方案,但没有成功。我忽略了在 Interface Builder 中连接 Table View Cells 有什么特别的魔力吗?或者换一种说法:target 对象是如何在运行时实际确定的,当 action 只是 File's Owner 中的一个类方法时(以及不同的控件何时会有所不同)都连接到一个公共超级视图的同一个所有者)?
以下是上下文的一些细节:
文件所有者设置为 NSWindowController 的子类,并且在那里正确继承到我的应用程序目标的模块。 可能相关:我没有使用 Storyboard,并且我的 XIB 大纲视图层次结构中的***对象是一个窗口 (NSPanel),而不是一个视图或视图控制器。 NSWindowController 仅作为文件所有者出现在 XIB 中(不在大纲视图中作为其自己的对象)。 在我尝试过的各种接线方案中(如下),Interface Builder“看起来”接线操作已成功。连接后,文件所有者的连接检查器在 Received Actions ("textCellChanged: ... [x] Table View Cell") 下列出预期的连接,以及将 NSTableView 超级视图中的组件连接到 NSViewController 中的其他方法的许多其他操作。 同样,在同一个 NSViewController 中将 NSTextField 作为 OUTLET 连接也没有问题。只有动作(或目标/动作??在 IB 中只设置“动作”)失败。 File Owner 也是 NSTableView 的数据源和委托,NSTextField 设置为 Action:Send on End of Editing 和 Behavior:Editable。我认为这些都与特定症状无关,这只是无法连接动作。 NSWindowController 是 Swift;我尝试在主 NSWindowController 实现或在实现 NSTableViewDelegate 的扩展中实现适当的操作,但效果没有明显不同。其他帖子暗示了 Xcode 接线中的错误,尽管在旧版本的 Xcode 中(我在 10.2 中)。以下是我尝试过的各种方法,结果都相似:
Ctrl+Drag 从 IB Outline View 中的 Table View Cell 图标到 NSWindowController 源模块,定位到现有的 @IBAction 或允许 Xcode 生成新的连接(类型 Action,Object:File's Owner)并使用它的新方法在视图控制器中 从@IBAction 旁边的源代码“左列单选圆圈”反向拖动到我的 .xib 大纲视图中的表格视图单元格 Ctrl+从表格视图单元格图标(在大纲视图中)拖动到占位符/文件所有者图标,然后从视图控制器中实现的方法的弹出列表中选择适当的操作方法。 可能还有其他一些最后,这里有一些相关的帖子以及它们之间的区别:
This 听起来像一个相同的症状,但在 cmets 中,OP 声称通过将文件所有者设置为视图控制器(完成)和解决阻止 XCode bugs(不可见)的组合解决了这个问题在我的上下文中)。
This 建议我链接到过时(已删除)的方法;当我允许 Xcode 为我创建方法时,绝对不是这种情况。
This unanswered post 建议用户放弃这种情况作为 IB 错误并优先选择非目标/操作解决方法。我想我可以继续收听 NSTextField 上的通知作为类似的解决方法。
最后,对于类似症状here 的公认答案是在这种情况下与文件所有者的连接不正确,其中文件所有者是 NSApplication 对象而不是视图控制器。在我的例子中,File Owner 是定义这些方法的 View Controller 对象,所以感觉是正确的目标。
这里有什么不遗余力的吗?提前感谢您的帮助。
【问题讨论】:
您说“文件所有者设置为 NSWindowController 的子类”和“文件所有者是视图控制器”。在 xib 和运行时哪个是正确的?文本字段的目标必须是表格视图的委托。 您在代码中重命名了您的属性,但您忘记了在 XIB/Storyboard 中有悬空指针,该指针仍然具有以前的属性名称。 @MarekH,我不这么认为。如果我在源中删除我的方法或在 IB 中删除我与它的有线连接,错误就会消失。如上所述,错误会在我连接到存在代码的 IBAction 后立即返回,或者让 IB 将新的 IBAction 存根添加到我的例程中。在这两种情况下,连接时都没有悬空指针。我认为问题在于在运行时它试图将当前例程连接到一个运行时对象,该对象不同于从同一视图指向同一源对象的其他类似操作的目标。 @Willeke,谢谢;我的意思是 NSWindowController 不是 ViewController (现在在上面固定)。 .xib 中的文件所有者是一个自定义类,是我的 NSWindowController 的后代。 .xib 大纲视图中的***对象是一个窗口,自定义类是我的 NSPanel 的后代。窗口的代表是文件所有者;文件所有者的“窗口”出口是 Window。文件所有者也是 Table View 的委托和数据源,以及从 Table View Cell(以及许多其他)接收到的操作的目标。除了 Table View Cell -> File Owner/NSWindowController 之外,所有这些连接都可以正常工作。 在窗口初始化期间是否在表格视图中加载行?你打电话给makeView(withIdentifier:owner:)
吗?哪个对象是所有者?
【参考方案1】:
xib 文件中的文件所有者是一个占位符对象,表示 nib 的所有者,并表示传递给makeView(withIdentifier:owner:)
的所有者对象。将 nib 的所有者(通常是视图控制器或窗口控制器)传递给 makeView(withIdentifier:owner:)
。
【讨论】:
这是我的问题——从我的 NSWindowController/NSTableViewDelegate 中调用 makeView() 时,我传递的是 nil 而不是 self,因此未能接收到魔法连接框架默认初始化程序授予 NIB 中典型 View 对象的权限对象,但不是那些只是您自己“制作”的视图模板的对象。谢谢你,@Willeke!以上是关于如何连接 NSTableView/Table View 以避免运行时错误“无法连接操作,目标类 NSObject 不响应”)的主要内容,如果未能解决你的问题,请参考以下文章