How do I send parameters using MonoTouch.ObjCRuntime.Selector and Perform Selector

c#, ios, iphone, monodevelop, xamarin.ios

Solution

The MonoTouch docs indicate that method maps to the Obj-C selector `performSelector:withObject:afterDelay`, which only supports invoking a selector with a single argument.

The best way to handle this depends what you need to do. One typical way to handle this would be to put the arguments as properties/fields on a single NSObject, then the target would be modified to have a single argument, and pull the real arguments off that method. If you did this with a custom MonoTouch object, you'd have to watch out for the GC collecting the managed peer, if nothing in managed code kept a reference to it.

A better solution would depend on exactly how you're using it. For example, in your example, you could trivially call the C# method directly, e.g.

_HandleSaveButtonTouchUpInside (url, data);

If you need to dispatch via Obj-C for some reason, but don't need the delay, use MonoTouch.ObjCRuntime.Messaging, e.g.

MonoTouch.ObjCRuntime.Messaging.void_objc_msgSend_IntPtr_IntPtr (
    target.Handle,
    MonoTouch.ObjCRuntime.Selector.GetHandle ("_HandleSaveButtonTouchUpInside"),
    arg0.Handle,
    arg1.Handle);

If you need the delay, you could use an NSTimer. MonoTouch has added special support for this to use an NSAction delegate, so you can use a C# lambda to capture arguments safely.

NSTimer.CreateScheduledTimer (someTimespan, () => _HandleSaveButtonTouchUpInside (url, data));

Problem

Here is an example I found, but they omitted actually sending the params. ``` this.PerformSelector(new MonoTouch.ObjCRuntime.Selector("_HandleSaveButtonTouchUpInside"),null,0.0f); [Export("_HandleSaveButtonTouchUpInside")] void _HandleSaveButtonTouchUpInside() { ... } ``` I would like to be able to do something like this: ``` this.PerformSelector(new MonoTouch.ObjCRuntime.Selector("_HandleSaveButtonTouchUpInside"),null,0.0f); [Export("_HandleSaveButtonTouchUpInside")] void _HandleSaveButtonTouchUpInside(NSURL url, NSData data) { ... } ``` How do I change the PerformSelector Call to send params to the method?

Original source