How to send parameters using MonoTouch.ObjCRuntime.Selector and Perform Selector

Here is an example that I found, but they did not indicate sending parameters at all.

this.PerformSelector(new MonoTouch.ObjCRuntime.Selector("_HandleSaveButtonTouchUpInside"),null,0.0f); [Export("_HandleSaveButtonTouchUpInside")] void _HandleSaveButtonTouchUpInside() { ... } 

I would like 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 call to PerformSelector to send parameters to a method?

+7
source share
2 answers

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

The best way to handle this is what you need to do. One of the typical ways to deal with this would be to put the arguments as properties / fields in one NSObject, then the target will be changed to have one argument, and get the real arguments from this method. If you did this using the special MonoTouch object, you would need to ensure that the GC builds a managed peer if nothing in the managed code contains a link to it.

The best solution will depend on how you use it. For example, in your example, you can trivially call the C # method directly, for example.

 _HandleSaveButtonTouchUpInside (url, data); 

If you need to send via Obj-C for some reason, but do not need to delay, use MonoTouch.ObjCRuntime.Messaging , for example

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

If you need a delay, you can use NSTimer . MonoTouch added special support for using the NSAction delegate, so you can use C # lambda to safely store arguments.

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

I also could not find a binding for this call. In the example below, I added my own overload for PerformSelector. Perhaps one of the Xamarin engineers can confirm this.

 using System; using MonoTouch.Foundation; using MonoTouch.UIKit; using MonoTouch.ObjCRuntime; using System.Runtime.InteropServices; namespace delete20120506 { [Register ("AppDelegate")] public partial class AppDelegate : UIApplicationDelegate { UIWindow window; public override bool FinishedLaunching (UIApplication app, NSDictionary options) { window = new UIWindow (UIScreen.MainScreen.Bounds); // Target target = new Target (); NSUrl url = new NSUrl ("http://xamarin.com/"); NSData nsData = NSData.FromString ("Hello"); target.PerformSelector (new MonoTouch.ObjCRuntime.Selector ("TestSelUrl:withData:"), url, nsData); window.MakeKeyAndVisible (); return true; } } [Register ("Target")] public class Target : NSObject { public Target () : base (NSObjectFlag.Empty) {} [Export("TestSelUrl:withData:")] void TestSelUrlWithData(NSUrl url, NSData nsData) { Console.WriteLine ("In TestSelUrlWithData"); Console.WriteLine (url.ToString ()); Console.WriteLine (nsData.ToString ()); return; } [DllImport ("/usr/lib/libobjc.dylib", EntryPoint = "objc_msgSend")] public static extern void void_objc_msgSend_intptr_intptr_intptr (IntPtr receiver, IntPtr selector, IntPtr arg1, IntPtr arg2, IntPtr arg3); [DllImport ("/usr/lib/libobjc.dylib", EntryPoint = "objc_msgSendSuper")] public static extern void void_objc_msgSendSuper_intptr_intptr_intptr (IntPtr receiver, IntPtr selector, IntPtr arg1, IntPtr arg2, IntPtr arg3); public virtual void PerformSelector (MonoTouch.ObjCRuntime.Selector sel, NSObject arg1, NSObject arg2) { if (this.IsDirectBinding) { void_objc_msgSend_intptr_intptr_intptr (this.Handle, Selector.GetHandle ("performSelector:withObject:withObject:"), sel.Handle, arg1.Handle, arg2.Handle); } else { void_objc_msgSendSuper_intptr_intptr_intptr (this.SuperHandle, Selector.GetHandle ("performSelector:withObject:withObject:"), sel.Handle, arg1.Handle, arg2.Handle); } } } } 
+4
source

All Articles