使用 ExportAttribute 实现非正式协议时如何调用基类/超类实现 (super.SomeMethod())

问题描述 投票:0回答:1

我有以下参考 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
,这将导致崩溃。

xamarin xamarin.mac
1个回答
0
投票

这应该可以做到:

base.PerformSelector(new ObjcRuntime.Selector("cancelOperation:"), this);

我建议先检查表视图是否真的可以响应选择器。由于苹果文档没有说 NSTableView 实现了这个方法。

if (base.RespondsToSelector(new ObjcRuntime.Selector("cancelOperation:")))
{
   base.PerformSelector(new ObjcRuntime.Selector("cancelOperation:"), this);
};
© www.soinside.com 2019 - 2024. All rights reserved.