2015-04-28 82 views
2

當結合的iOS lib.a爲Xamarin,我發現了以下錯誤:產生Objective Sharpie難度結合的iOS委託方法沒有參數

btouch: The delegate method Device.SomeDeviceDelegate.CaptureComplete needs to take at least one parameter (BI1003) 

的綁定。

namespace Device 
{ 

    // @protocol SomeDeviceDelegate <NSObject> 
    [Protocol, Model, Preserve] 
    [BaseType(typeof(NSObject))] 
    interface SomeDeviceDelegate 
    { 
     // @optional -(void)CaptureComplete; 
     [Export("CaptureComplete")] 
     void CaptureComplete(); 
    } 

    // @interface SomeDevice : NSObject 
    [Protocol, Model, Preserve] 
    [BaseType(typeof(NSObject), Delegates = new[] { "WeakDelegate" }, Events = new[] { typeof(SomeDeviceDelegate) })] 
    interface SomeDevice 
    { 
     [Wrap("WeakDelegate")] 
     SomeDeviceDelegate Delegate { get; set; } 

     // @property (assign, nonatomic) id<SomeDeviceDelegate> delegate; 
     [NullAllowed, Export("delegate", ArgumentSemantic.Assign)] 
     SomeDeviceDelegate WeakDelegate { get; set; } 
    } 

} 

NB。我已將名稱更改爲SomeDevice以隱藏硬件/設備名稱(NDA)。

編譯器抱怨// @optional -(void)CaptureComplete;和相應的綁定CaptureComplete()沒有參數,它至少需要一個。

問:我需要做什麼來綁定這個委託?

我曾嘗試Binding Types Reference Guide並試圖運用

  • EventArgs屬性
  • NoDefaultValue屬性
  • DefaultValueFromArgument屬性

UPDATE

我誤解了NoDefaultValueDefaultValueFromArgument屬性,它們在代理返回一個值時使用(例如,因爲回報會干擾Xamarin包裝的事件。

回答

2

我昨天晚些時候發現瞭解決方案,併爲遇到相同錯誤消息的其他人解決了這個問題。

注意:這次沒有更改名稱,因爲它使答案不太清楚。

處理ObjC委託的首選方法是將它們公開爲事件,例如,

// @interface ICBarCodeReader : ICISMPDevice 
[DisableDefaultCtor] 
[BaseType(typeof(ICISMPDevice), Delegates = new[] { "WeakDelegate" }, Events = new[] { typeof(ICBarCodeReaderDelegate) }))] 
public interface ICBarCodeReader 
{ 
    [Wrap("WeakDelegate")] 
    ICBarCodeReaderDelegate Delegate { get; set; } 

    // @property (assign, nonatomic) id<ICISMPDeviceDelegate,ICBarCodeReaderDelegate> delegate; 
    [NullAllowed, Export("delegate", ArgumentSemantic.Assign)] 
    ICBarCodeReaderDelegate WeakDelegate { get; set; } 
} 

BaseType的Delegate和Events參數生成包裝ICBarCodeReaderDelegate上每個方法的代碼。

// @protocol ICBarCodeReaderDelegate 
[Protocol, Model, Preserve] 
[BaseType(typeof(ICISMPDeviceDelegate))] 
public interface ICBarCodeReaderDelegate 
{ 
    // @required -(void)barcodeData:(id)data ofType:(int)type; 
    [Abstract] 
    [Export("barcodeData:ofType:")] 
    [EventArgs("BarcodeData")] 
    void BarcodeData(string data, BarCodeSymbologies type); 

    // @required -(void)configurationRequest; 
    [Abstract] 
    [Export("configurationRequest")] 
    void ConfigurationRequest(); 
} 

,它允許你在你的項目做:當方法沒有參數,由btouch錯誤消息告訴

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

但是這種方法失敗。

我只發現了另一種方法(現在顯得簡單直接),並不是將委託作爲事件包裝,

// @interface ICBarCodeReader : ICISMPDevice 
[DisableDefaultCtor] 
[BaseType(typeof(ICISMPDevice))] 
public interface ICBarCodeReader 
{ 
    [Wrap("WeakDelegate")] 
    ICBarCodeReaderDelegate Delegate { get; set; } 

    // @property (assign, nonatomic) id<ICISMPDeviceDelegate,ICBarCodeReaderDelegate> delegate; 
    [NullAllowed, Export("delegate", ArgumentSemantic.Assign)] 
    ICBarCodeReaderDelegate WeakDelegate { get; set; } 
} 

而是創建一個Delegate接口的實現。

例如

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; 
} 

我希望這可以幫助別人。

0

「CaptureComplete:」可能會期待發件人?

+0

這就是我的想法,但是ObjC簽名並不表示它確實如此。我嘗試向託管方法中添加一個參數,但是這又產生了另一個「註冊服務商」在進一步發現方法錯誤時發現了簽名不匹配。 – Dennis

+0

我已經將':'添加到'[Export()]'並且它現在編譯。 – Dennis

+0

不幸的是,在運行時''ObjCRuntime.RuntimeException:Wrapper類型'Device.SomeDeviceDelegate'缺少其原生的ObjectiveC類'SomeDeviceDelegate'。' – Dennis