没有参数的iOS委托方法难以绑定
Posted
技术标签:
【中文标题】没有参数的iOS委托方法难以绑定【英文标题】:Difficulty binding iOS delegate method without parameters 【发布时间】:2015-07-06 17:40:39 【问题描述】:为 Xamarin 绑定 ios lib.a 时,出现以下错误:
btouch: The delegate method Device.SomeDeviceDelegate.CaptureComplete needs to take at least one parameter (BI1003)
绑定已生成Objective Sharpie。
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;
注意。我已将名称更改为 SomeDevice
以隐藏硬件/设备名称 (NDA)。
编译器抱怨// @optional -(void)CaptureComplete;
和各自的绑定CaptureComplete()
没有参数并且它至少需要一个。
问:我需要做什么来绑定这个委托?
我已经尝试过Binding Types Reference Guide 并尝试过应用
EventArgs
属性
NoDefaultValue
属性
DefaultValueFromArgument
属性
更新
我误解了 NoDefaultValue
和 DefaultValueFromArgument
属性,它们在委托返回值(例如 bool
)时使用,因为返回会干扰事件的 Xamarin 包装。
【问题讨论】:
【参考方案1】:我找到了解决办法。
注意:这次我没有更改名称,因为它使答案不太清楚。
处理 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();
这允许你在你的项目中做:
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);
但是,当方法没有参数时,这种方法会失败,如 btouch 错误消息所示。
我发现的另一种方法(现在看起来简单明了)不是将委托包装为事件,例如
// @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;
【讨论】:
【参考方案2】:“CaptureComplete:”可能正在等待发件人?
【讨论】:
这就是我的想法,但是 ObjC 签名并不表明它确实如此。我尝试向托管方法添加一个参数,但随后又产生了另一个registrar found a signature mismatch in the method
错误。
我已将:
添加到[Export()]
,现在可以编译了。
这很遗憾在运行时失败,ObjCRuntime.RuntimeException: Wrapper type 'Device.SomeDeviceDelegate' is missing its native ObjectiveC class 'SomeDeviceDelegate'.
这不是解决方案。以上是关于没有参数的iOS委托方法难以绑定的主要内容,如果未能解决你的问题,请参考以下文章
使用委托从iOS中的ViewModel传递数据到UI的任何替代方法?
[ 面试没回答上的问题2]IOS上给body绑定click事件的bug