2012-05-07 4 views
7

यहां एक उदाहरण दिया गया है, लेकिन वे वास्तव में पैराम भेज रहे हैं।मैं MonoTouch.ObjCRuntime का उपयोग करके पैरामीटर कैसे भेजूं। चयनकर्ता और प्रदर्शनकर्ता

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 कॉल मैं बदल सकता हूँ?

उत्तर

9

MonoTouch docs से संकेत मिलता है Obj सी चयनकर्ता performSelector:withObject:afterDelay है, जो केवल एक ही तर्क के साथ एक चयनकर्ता लागू करने का समर्थन करता है कि विधि नक्शे।

इसे संभालने का सबसे अच्छा तरीका यह निर्भर करता है कि आपको क्या करना है। इसे संभालने का एक सामान्य तरीका तर्कों को एक एनएसओब्जेक्ट पर गुण/फ़ील्ड के रूप में रखना होगा, फिर लक्ष्य को एक तर्क के लिए संशोधित किया जाएगा, और उस विधि से वास्तविक तर्क खींचें। यदि आपने कस्टम मोनो टच ऑब्जेक्ट के साथ ऐसा किया है, तो आपको प्रबंधित पीयर को एकत्रित करने के लिए जीसी के लिए देखना होगा, अगर प्रबंधित कोड में कुछ भी इसका संदर्भ नहीं रखता है।

एक बेहतर समाधान इस बात पर निर्भर करेगा कि आप इसका उपयोग कैसे कर रहे हैं। उदाहरण के लिए, आपके उदाहरण में, आप सीधे सी # विधि को सीधे कॉल कर सकते हैं, उदा।

_HandleSaveButtonTouchUpInside (url, data); 

आप किसी कारण से Obj सी के माध्यम से प्रेषण करने के लिए की जरूरत है, लेकिन देरी की जरूरत नहीं है, का उपयोग MonoTouch.ObjCRuntime.Messaging, उदा

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

आप देरी की जरूरत है, तो आप एक NSTimer इस्तेमाल कर सकते हैं। मोनो टच ने NSAction प्रतिनिधि का उपयोग करने के लिए इसके लिए विशेष समर्थन जोड़ा है, ताकि आप सुरक्षित रूप से तर्कों को कैप्चर करने के लिए सी # लैम्ब्डा का उपयोग कर सकें।

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

पूरी तरह से जवाब mhutch के लिए धन्यवाद। मैं PerformSelector का उपयोग कर रहा हूं जब मुझे मुख्य धागे को मुक्त करने की आवश्यकता होती है ताकि कोको स्क्रीन को फिर से चलाए, और फिर मैं कुछ तर्क को संसाधित करने के लिए वापस आ सकता हूं। अभी मैं एक प्रगति पट्टी के समतुल्य को अद्यतन करने की कोशिश कर रहा हूं जिसे लूप के लिए लिखने के दौरान स्क्रीन पर खींचा गया है। यह देखना चाहता था कि क्या मैं लूप के भीतर एक प्रदर्शन चयनकर्ता डालकर और प्रगति पट्टी की संपत्ति को अद्यतन करके स्क्रीन को ताज़ा कर सकता हूं। –

+0

ऐसा करने का एक और तरीका तर्क/स्ट्रीम के लिए थ्रेड का उपयोग करना होगा, और यूआई को अपडेट करने के लिए थ्रेड से InvokeOnMainThread का उपयोग करना होगा। –

+0

इसने मुझे पुस्तकालय को मैन्युअल रूप से पुनर्निर्मित करने से बचाया क्योंकि मूल डेवलपर ने किसी विशेष संपत्ति को बाध्य नहीं किया था, या स्रोत को छोड़ दिया था, इसलिए धन्यवाद। रुचि रखने वाले किसी भी व्यक्ति के लिए, setColor को कॉल करके आसानी से msgSend_IntPtr_IntPtr विधि का उपयोग करके गुणों को सेट किया जा सकता है: जहां रंग संपत्ति का नाम है। (Arg 0 संपत्ति मूल्य है, Arg 1 = IntPtr.Zero) – Dermot

4

मुझे इस कॉल के लिए बाध्यकारी नहीं मिला। नीचे दिए गए नमूने में मैंने PerformSelector के लिए अपना स्वयं का अधिभार जोड़ा। शायद एक्समरिन इंजीनियर्स में से एक इसकी पुष्टि कर सकता है।

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); 
      } 
     } 
    } 
} 
+0

मोनोटouch चयनकर्ता का बहुत बढ़िया ओवरलोडिंग! मैं इसे अपने प्रोजेक्ट होम्स में आजमा सकता हूं। साझा करने के लिए धन्यवाद। मुझे आशा है कि जो लोग प्रदर्शन चयनकर्ता की तलाश में हैं वे इस प्रश्न पर आ जाएंगे। –

संबंधित मुद्दे

 संबंधित मुद्दे