为 Xamarin 绑定(bind) iOS lib.a 时,出现以下错误:
btouch: The delegate method Device.SomeDeviceDelegate.CaptureComplete needs to take at least one parameter (BI1003)
绑定(bind)已生成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;
和相应的绑定(bind) CaptureComplete()
没有参数,并且至少需要一个参数。
问:我需要做什么来绑定(bind)这个委托(delegate)?
我试过 Binding Types Reference Guide并尝试应用
EventArgs
属性NoDefaultValue
属性DefaultValueFromArgument
属性更新
我误解了 NoDefaultValue
和 DefaultValueFromArgument
属性,它们在委托(delegate)返回值(例如 bool
)时使用,因为返回会干扰事件的 Xamarin 包装。
我找到了解决办法。
注意:这次我没有更改名称,因为它使答案不太清楚。
处理 ObjC 委托(delegate)的首选方式是将它们公开为事件,例如
// @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)barcodeDataid)data ofTypeint)type;
[Abstract]
[Export("barcodeDatafType:")]
[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 错误消息所示。
我发现的另一种方法(现在看起来简单明了)不是将委托(delegate)包装为事件,例如
// @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 接口(interface)的实现。
例如
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;
}
关于c# - 没有参数的iOS委托(delegate)方法难以绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29909810/
欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) | Powered by Discuz! X3.4 |