我有以下参考 swift 代码,我正在尝试在 xamain.mac 中实现同样的事情。
class MyTableView : NSTableView {
override func cancelOperation(_ sender: Any?) {
// some custom processing goes here
super.cancelOperation(sender)
// another part of custom processing goes here
}
}
问题是在 C# 中
NSTableView
没有实现 cancelOperation:
,所以没有什么可以覆盖的。
我能够通过我的
NSTableView
子类中的直接导出来处理消息:
[Export("cancelOperation:")]
private void CancelOperation(NSObject? sender)
{
// some custom processing
System.Diagnostics.Debug.WriteLine("Custom processing");
//won't compile
//base.CancelOperation(sender);
//crashes the app
objc_msgSendSuper(this.SuperHandle, Selector.GetHandle("cancelOperation:"),
sender?.Handle ?? NativeHandle.Zero);
//another part of custom processing
System.Diagnostics.Debug.WriteLine("another part of custom processing");
}
[DllImport ("/usr/lib/libobjc.dylib", EntryPoint = "objc_msgSend")]
private static extern void objc_msgSendSuper(NativeHandle superReceiver,
NativeHandle selector,
NativeHandle value);
然后问题是我无法像 Swift 代码那样调用
base/super
实现。我不能只写base.CancelOperation(sender)
,因为这不是重写的成员,而是直接导出。
作为一种解决方法,我尝试使用
objc_msgSendSuper
,但这会使应用程序崩溃(很可能是因为我做错了)。
所以,问题是 - 如何实现
cancelOperation:
(或非正式协议的其他成员)的自定义处理程序,并从这样的处理程序调用 base/super
实现。
可以在此处下载演示该问题的测试项目。只需在表格的第二列中输入一些内容,然后按 Esc 键即可。由于
objc_msgSendSuper
处理程序内的 MyNSTableView.CancelOperation
,这将导致崩溃。
这应该可以做到:
base.PerformSelector(new ObjcRuntime.Selector("cancelOperation:"), this);
我建议先检查表视图是否真的可以响应选择器。由于苹果文档没有说 NSTableView 实现了这个方法。
if (base.RespondsToSelector(new ObjcRuntime.Selector("cancelOperation:")))
{
base.PerformSelector(new ObjcRuntime.Selector("cancelOperation:"), this);
};