菜鸟教程小白 发表于 2022-12-12 15:08:34

c# - 没有参数的iOS委托(delegate)方法难以绑定(bind)


                                            <p><p>为 Xamarin 绑定(bind) iOS lib.a 时,出现以下错误:</p>

<pre><code>btouch: The delegate method Device.SomeDeviceDelegate.CaptureComplete needs to take at least one parameter (BI1003)
</code></pre>

<p>绑定(bind)已生成<a href="http://developer.xamarin.com/guides/ios/advanced_topics/binding_objective-c/objective_sharpie/" rel="noreferrer noopener nofollow">Objective Sharpie</a> .</p>

<pre class="lang-cs prettyprint-override"><code>namespace Device
{   

    // @protocol SomeDeviceDelegate &lt;NSObject&gt;
   
   
    interface SomeDeviceDelegate
    {
      // @optional -(void)CaptureComplete;
      
      void CaptureComplete();
    }

    // @interface SomeDevice : NSObject
   
    { &#34;WeakDelegate&#34; }, Events = new[] { typeof(SomeDeviceDelegate) })]
    interface SomeDevice
    {
      
      SomeDeviceDelegate Delegate { get; set; }

      // @property (assign, nonatomic) id&lt;SomeDeviceDelegate&gt; delegate;
      
      SomeDeviceDelegate WeakDelegate { get; set; }
    }

}
</code></pre>

<p><em>注意。我已将名称更改为 <code>SomeDevice</code> 以隐藏硬件/设备名称 (NDA)。</em></p>

<p>编译器提示 <code>//@optional -(void)CaptureComplete;</code> 和相应的绑定(bind) <code>CaptureComplete()</code> 没有参数,并且至少需要一个参数。 </p>

<p><strong>问:</strong>我需要做什么来绑定(bind)这个委托(delegate)?</p>

<p>我试过 <a href="http://developer.xamarin.com/guides/ios/advanced_topics/binding_objective-c/binding_types_reference_guide/" rel="noreferrer noopener nofollow">Binding Types Reference Guide</a>并尝试应用</p>

<ul>
<li><code>EventArgs</code> 属性</li>
<li><code>NoDefaultValue</code> 属性</li>
<li><code>DefaultValueFromArgument</code> 属性</li>
</ul>

<p><strong>更新</strong></p>

<p>我误解了 <code>NoDefaultValue</code> 和 <code>DefaultValueFromArgument</code> 属性,它们在委托(delegate)返回值(例如 <code>bool</code>)时使用,因为返回会干扰事件的 Xamarin 包装。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>我找到了解决办法。</p>
<p><em>注意:这次我没有更改名称,因为它使答案不太清楚。</em></p>
<p>处理 ObjC 委托(delegate)的首选方式是将它们公开为事件,例如</p>
<pre><code>// @interface ICBarCodeReader : ICISMPDevice

{ &#34;WeakDelegate&#34; }, Events = new[] { typeof(ICBarCodeReaderDelegate) }))]
public interface ICBarCodeReader
{
   
    ICBarCodeReaderDelegate Delegate { get; set; }

    // @property (assign, nonatomic) id&lt;ICISMPDeviceDelegate,ICBarCodeReaderDelegate&gt; delegate;
   
    ICBarCodeReaderDelegate WeakDelegate { get; set; }
}
</code></pre>
<p>BaseType 的 Delegate 和 Events 参数,生成包装 ICBarCodeReaderDelegate 上的每个方法的代码。</p>
<pre><code>// @protocol ICBarCodeReaderDelegate


public interface ICBarCodeReaderDelegate
{
    // @required -(void)barcodeData:(id)data ofType:(int)type;
   
   
   
    void BarcodeData(string data, BarCodeSymbologies type);

    // @required -(void)configurationRequest;
   
   
    void ConfigurationRequest();
}
</code></pre>
<p>这允许你在你的项目中做:</p>
<pre><code>public void Init()
{
    _sharedBarCodeReader.BarcodeData += OnBarcodeData;
}

private void OnBarcodeData(object sender, BarcodeDataEventArgs e)
{
    var barcode = Convert.ToString(sender); // this maps to string data
    //BarCodeSymbologies is in BarcodeDataEventArgs

    var handler = BarCodeData;
    if (handler != null)
      handler(this, barcode);
}
</code></pre>
<p>但是,当方法没有参数时,这种方法会失败,如 btouch 错误消息所示。</p>
<p>我发现的另一种方法(现在看起来简单明了)不是将委托(delegate)包装为事件,例如</p>
<pre><code>// @interface ICBarCodeReader : ICISMPDevice


public interface ICBarCodeReader
{
   
    ICBarCodeReaderDelegate Delegate { get; set; }

    // @property (assign, nonatomic) id&lt;ICISMPDeviceDelegate,ICBarCodeReaderDelegate&gt; delegate;
   
    ICBarCodeReaderDelegate WeakDelegate { get; set; }
}
</code></pre>
<p>并改为创建 Delegate 接口(interface)的实现。</p>
<p>例如</p>
<pre><code>public void Init()
{
    _sharedBarCodeReader.Delegate = new BarCodeReaderDelegate(this);
}

private class BarCodeReaderDelegate : ICBarCodeReaderDelegate
{
    public BarCodeReaderDelegate(BarCodeScanner barCodeScanner)
    {
      _barCodeScanner = barCodeScanner;
    }

    public override void BarcodeData(string data, BarCodeSymbologies type)
    {
      var handler = _barCodeScanner.BarCodeData;
      if (handler != null)
            handler(this, data);
    }

    public override void ConfigurationRequest() { }

    private readonly BarCodeScanner _barCodeScanner;
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于c# - 没有参数的iOS委托(delegate)方法难以绑定(bind),我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/29909810/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/29909810/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: c# - 没有参数的iOS委托(delegate)方法难以绑定(bind)