7

これは私が見つけた例ですが、実際にパラメーターを送信することを省略しました。

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

[Export("_HandleSaveButtonTouchUpInside")]
    void _HandleSaveButtonTouchUpInside()
    {
...
}

私はこのようなことができるようにしたいと思います:

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

[Export("_HandleSaveButtonTouchUpInside")]
    void _HandleSaveButtonTouchUpInside(NSURL url, NSData data)
    {
...
}

メソッドにパラメーターを送信するように PerformSelector Call を変更するにはどうすればよいですか?

4

2 に答える 2

9

MonoTouchのドキュメントは、メソッドがObj-CセレクターperformSelector:withObject:afterDelayにマップされることを示しています。これは、単一の引数でセレクターを呼び出すことのみをサポートします。

これを処理する最良の方法は、何をする必要があるかによって異なります。これを処理する一般的な方法の1つは、引数をプロパティ/フィールドとして単一のNSObjectに配置し、ターゲットを変更して単一の引数を持ち、そのメソッドから実際の引数を取得することです。カスタムMonoTouchオブジェクトを使用してこれを行った場合、マネージコードに参照が保持されていない場合は、GCがマネージピアを収集することに注意する必要があります。

より良い解決策は、それをどのように使用しているかによって異なります。たとえば、あなたの例では、C#メソッドを直接簡単に呼び出すことができます。

_HandleSaveButtonTouchUpInside (url, data);

何らかの理由でObj-C経由でディスパッチする必要があるが、遅延は必要ない場合は、MonoTouch.ObjCRuntime.Messagingを使用します。

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

遅延が必要な場合は、NSTimerを使用できます。MonoTouchは、NSActionデリゲートを使用するための特別なサポートを追加したため、C#ラムダを使用して引数を安全にキャプチャできます。

NSTimer.CreateScheduledTimer (someTimespan, () => _HandleSaveButtonTouchUpInside (url, data));
于 2012-05-07T02:59:11.410 に答える
4

この呼び出しのバインディングも見つかりませんでした。以下のサンプルでは、​​PerformSelector に独自のオーバーロードを追加しました。おそらく、Xamarin エンジニアの 1 人がこれを確認できます。

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);
            }
        }
    }
}
于 2012-05-07T02:36:02.877 に答える