gpt4 book ai didi

c# - 为类和协议(protocol)创建 Xamarin iOS 绑定(bind)

转载 作者:行者123 更新时间:2023-12-01 22:46:35 25 4
gpt4 key购买 nike

目标

我们正在尝试编译 route-me iOS SDK(Alpstein、MapBox 或 xmap)的最新分支,并从中创建一个 Xamarin 绑定(bind)项目。

我们已经尝试过的代码可以在这些存储库中找到(按新鲜度降序排列):

  • xmap - https://github.com/sw897/xmap-ios-sdk
  • map 框 - https://github.com/mapbox/mapbox-ios-sdk
  • 阿尔普斯坦 - https://github.com/Alpstein/route-me
  • 路由我 - https://github.com/route-me/route-me

  • 问题

    不幸的是,我们被困在一个相当初始的阶段。 route-me 需要一个 TileSource 来提供要在 Canvas 上绘制的图 block 。因此,我们需要通过绑定(bind)将 RMAbstractWebMapSource 类公开给我们的 C# Xamarin 客户端代码。由于该类继承自 RMAbstractMercatorTileSource 类,因此我们也需要绑定(bind)该类。最后我们必须绑定(bind) RMAbstractMercatorTileSource 实现的 RMTileSource 协议(protocol)。

    以下是 Objective-C 源码中相关类和协议(protocol)的定义:

    RMAbstractWebMapSource

    RMAbstractWebMapSource.h 中定义的抽象类
    @interface RMAbstractWebMapSource : RMAbstractMercatorTileSource

    RMAbstractMercatorTileSource

    RMAbstractMercatorTileSource.h 中定义的抽象类
    @interface RMAbstractMercatorTileSource : NSObject <RMTileSource>

    RMTileSource

    RMTileSource.h 中定义的协议(protocol)
    @protocol RMTileSource <NSObject>

    C#-绑定(bind)
    [BaseType (typeof (RMAbstractMercatorTileSource))]
    public partial interface RMAbstractWebMapSource { ... }

    [BaseType (typeof (NSObject))]
    public partial interface RMAbstractMercatorTileSource : RMTileSource { ... }

    [Model, Protocol, BaseType (typeof (NSObject))]
    public partial interface RMTileSource { ... }

    这些绑定(bind)编译得很好。但是在运行时..

    客户端代码使用
    RMAbstractWebMapSource tileSource = new MyTileSource(1234);

    其中 MyTileSource 定义为:
    public sealed class MyTileSource: RMAbstractWebMapSource { ... }

    错误

    在实例化 MyTileSource 对象(构造函数调用)时会引发以下运行时错误,同时使应用程序崩溃:
    NSForwarding: warning: object [0x...] of class 'MyProject_MyTileSource' does not implement methodSignatureForSelector: -- trouble ahead
    NSForwarding: warning: object [0x...] of class 'MyProject_MyTileSource' does not implement doesNotRecognizeSelector: -- abort

    小径

    前面的麻烦

    可以通过 Google 找到此错误消息(例如 http://www.touch-code-magazine.com/does-not-implement-methodsignatureforselector-trouble-ahead/)。在网上找到的答案表明继承存在问题。似乎 MyTileSource 类没有像应有的那样从 NSObject 继承。但是,从 Xamarin Bindings 项目(生成后在 ProjectDir/obj 中找到)生成的代码另有说明:
    public unsafe abstract partial class RMAbstractWebMapSource : RMAbstractMercatorTileSource { ... }
    public unsafe partial class RMAbstractMercatorTileSource : NSObject, IRMTileSource { ... }
    public unsafe partial class RMTileSource : NSObject, IRMTileSource { ... }
    public interface IRMTileSource : INativeObject, IDisposable { ... }

    选择器

    我们无法确定哪个选择器失败。试图在 MyTileSource 中覆盖 void DoesNotRecognizeSelector(Selector sel) 会产生一个不同的错误:
    NSForwarding: warning: object [0x...] of class 'MyProject_MyTileSource' does not implement methodSignatureForSelector: -- trouble ahead
    ...(200x)...
    NSForwarding: warning: object [0x...] of class 'MyProject_MyTileSource' does not implement methodSignatureForSelector: -- trouble ahead

    最后, native 代码因段错误 (SIGSEGV) 而崩溃。这次我们还从单声道运行时获得了堆栈跟踪。它基本上从 MyTileSource 的构造函数的调用开始并在 NSObject 中消失,据我们所见:
    mono-rt:   at <unknown> <0xffffffff>
    mono-rt: at (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging.intptr_objc_msgSend (intptr,intptr) <IL 0x00026, 0xffffffff>
    mono-rt: at MonoTouch.Foundation.NSObject.AllocIfNeeded () [0x00015] in /Developer/MonoTouch/Source/maccore/src/Foundation/NSObject2.cs:390
    mono-rt: at MonoTouch.Foundation.NSObject..ctor (MonoTouch.Foundation.NSObjectFlag) [0x00006] in /Developer/MonoTouch/Source/maccore/src/Foundation/NSObject2.cs:102
    mono-rt: at XMap.RMAbstractMercatorTileSource..ctor (MonoTouch.Foundation.NSObjectFlag) <IL 0x00002, 0x0002b>
    mono-rt: at XMap.RMAbstractWebMapSource..ctor () <IL 0x00006, 0x00033>
    mono-rt: at Saalplan.RxTileSource..ctor (int) [0x00000] in /Users/rxDeveloper/Projects/rx.app.seatingmap/Xamarin.iOS/RxTileSource.cs:12
    mono-rt: at Saalplan.TileViewController.InitMapView () [0x00006] in /Users/rxDeveloper/Projects/rx.app.seatingmap/Xamarin.iOS/TileViewController.cs:24
    mono-rt: at Saalplan.TileViewController.ViewDidLoad () [0x00008] in /Users/rxDeveloper/Projects/rx.app.seatingmap/Xamarin.iOS/

    问题

    绑定(bind)继承和协议(protocol)实现的这种组合的正确方法是什么?

    最佳答案

    我们现在让绑定(bind)工作了。问题是我们的 linkwith.cs 文件。使用上述绑定(bind)和以下 linkwith.cs 文件有效:

    [assembly: LinkWith ("libXMap.a", LinkTarget.ArmV7 | LinkTarget.ArmV7s | LinkTarget.Simulator, Frameworks = "CoreLocation QuartzCore UIKit Foundation CoreGraphics", LinkerFlags = "-lz -lsqlite3", ForceLoad = true, IsCxx = true)]

    关于c# - 为类和协议(protocol)创建 Xamarin iOS 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25081152/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com