访问BBDeviceController.SharedController为空的技术问题求助
我来帮你拆解这个Xamarin.iOS绑定Objective-C库时遇到的SharedController返回null的问题,结合你的代码和描述,给出几个可行的解决方向:
1. 先排查OC原生单例的实现逻辑
首先,Objective-C里的+sharedController是标准的单例方法,正常情况下它的内部应该会完成实例的初始化(比如用dispatch_once保证线程安全)。虽然你没提供.m文件,但根据官方文档的用法[[BBDeviceController sharedController] setDelegate:self],原生库应该是支持这个单例的,所以问题大概率出在绑定后的API定义上。
2. 调整API定义:把属性改回静态方法
你提到手动添加了[Static]才能访问SharedController,而且生成的代码带有[Verify(MethodToProperty)]标记——这是Objective Sharpie把OC类方法转成C#属性的提示,但有时候这种转换会导致初始化逻辑失效。
你可以把生成的属性定义改成静态方法:
[BaseType(typeof(NSObject))] interface BBDeviceController { // 替换原来的属性定义为静态方法 [Static] [Export("sharedController")] BBDeviceController SharedController(); ... }
然后在调用时用方法调用的方式:
public override void ViewDidLoad() { base.ViewDidLoad(); bbDeviceController = BBDeviceController.SharedController(); // 这里改成方法调用 ConnectDevice(); }
这种方式更贴近OC原生的调用逻辑,大概率能解决null的问题。
3. 检查是否需要预初始化原生库
有些第三方OC库需要先执行初始化步骤(比如全局配置、授权等)才能让单例正常工作。你可以仔细查看原生库的文档,确认是否有类似[BBDeviceController setup]或者[BBDeviceController initialize]这样的方法,在调用SharedController之前先执行这些初始化操作。
4. 手动实例化的替代方案
如果单例方法确实无法正常工作,你可以尝试手动实例化BBDeviceController——因为它是NSObject的子类,理论上可以通过构造函数创建:
public override void ViewDidLoad() { base.ViewDidLoad(); bbDeviceController = new BBDeviceController(); // 手动实例化 bbDeviceController.Delegate = this; // 对应OC的setDelegate:self ConnectDevice(); }
注意:原OC类的delegate是weak修饰的,在Xamarin中要确保你的控制器实例不会被GC回收,所以要把bbDeviceController声明为类的强引用成员(你已经这么做了),避免Delegate被意外回收。
5. 验证绑定的构造函数是否正确
你需要确认生成的API定义中包含了BBDeviceController的默认构造函数绑定,如果没有,要手动添加:
[BaseType(typeof(NSObject))] interface BBDeviceController { // 添加默认构造函数绑定 [Export("init")] BBDeviceController Constructor(); ... }
只有这样,你才能在C#中正常实例化该类。
内容的提问来源于stack exchange,提问作者rgahan

