如何使用MonoTouch.ObjCRuntime.Selector和Perform Selector发送参数

Pio*_*sik 7 c# iphone monodevelop xamarin.ios ios

这是我发现的一个例子,但它们实际上省略了发送参数.

this.PerformSelector(new MonoTouch.ObjCRuntime.Selector("_HandleSaveButtonTouchUpInside"),null,0.0f);

[Export("_HandleSaveButtonTouchUpInside")]
    void _HandleSaveButtonTouchUpInside()
    {
...
}
Run Code Online (Sandbox Code Playgroud)

我希望能够做到这样的事情:

this.PerformSelector(new MonoTouch.ObjCRuntime.Selector("_HandleSaveButtonTouchUpInside"),null,0.0f);

[Export("_HandleSaveButtonTouchUpInside")]
    void _HandleSaveButtonTouchUpInside(NSURL url, NSData data)
    {
...
}
Run Code Online (Sandbox Code Playgroud)

如何更改PerformSelector Call以将params发送到方法?

Mik*_*son 9

所述的MonoTouch文档指示方法映射到对象-选择器performSelector:withObject:afterDelay,其仅支持一个参数调用的选择器.

处理此问题的最佳方法取决于您需要做什么.处理此问题的一种典型方法是将参数作为属性/字段放在单个NSObject上,然后将目标修改为具有单个参数,并从该方法中提取实际参数.如果您使用自定义MonoTouch对象执行此操作,则必须注意收集托管对等方的GC,如果托管代码中没有任何内容保留对它的引用.

更好的解决方案取决于您使用它的确切方式.例如,在您的示例中,您可以直接调用C#方法,例如

_HandleSaveButtonTouchUpInside (url, data);
Run Code Online (Sandbox Code Playgroud)

如果由于某种原因需要通过Obj-C发送,但不需要延迟,请使用MonoTouch.ObjCRuntime.Messaging,例如

MonoTouch.ObjCRuntime.Messaging.void_objc_msgSend_IntPtr_IntPtr (
    target.Handle,
    MonoTouch.ObjCRuntime.Selector.GetHandle ("_HandleSaveButtonTouchUpInside"),
    arg0.Handle,
    arg1.Handle);
Run Code Online (Sandbox Code Playgroud)

如果您需要延迟,可以使用NSTimer.MonoTouch为此添加了特殊支持以使用NSAction委托,因此您可以使用C#lambda安全地捕获参数.

NSTimer.CreateScheduledTimer (someTimespan, () => _HandleSaveButtonTouchUpInside (url, data));
Run Code Online (Sandbox Code Playgroud)