我们正在尝试编译路由器iOS SDK(Alpstein,MapBox或xmap)的最新分支,并从中创建一个Xamarin绑定项目。
我们已经尝试过的代码可以在这些存储库中找到(按照新鲜度的降序排列):
不幸的是,我们陷入了初期阶段。 route-me需要一个TileSource来提供要在画布上绘制的图块。因此,我们需要通过绑定将RMAbstractWebMapSource类公开给我们的C#Xamarin客户端代码。由于此类继承自RMAbstractMercatorTileSource类,因此我们也需要绑定该类。最后,我们必须绑定RMAbstractMercatorTileSource实现的RMTileSource协议。
以下是Objective-C源中相关类和协议的定义:
RMAbstractWebMapSource.h中定义的抽象类
@interface RMAbstractWebMapSource : RMAbstractMercatorTileSource
RMAbstractMercatorTileSource.h中定义的抽象类
@interface RMAbstractMercatorTileSource : NSObject <RMTileSource>
RMTileSource.h中定义的协议
@protocol RMTileSource <NSObject>
[BaseType (typeof (RMAbstractMercatorTileSource))]
public partial interface RMAbstractWebMapSource { ... }
[BaseType (typeof (NSObject))]
public partial interface RMAbstractMercatorTileSource : RMTileSource { ... }
[Model, Protocol, BaseType (typeof (NSObject))]
public partial interface RMTileSource { ... }
这些Bindings编译得很好。但是在运行时......
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
最后,本机代码崩溃并出现分段错误(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/
绑定这种继承和协议实现的组合的正确方法是什么?
答案 0 :(得分:0)
您是否看过现有的monotouch绑定示例?你可以在这里找到它:
https://github.com/mono/monotouch-bindings/tree/master/Route-Me
答案 1 :(得分:0)
我们现在正在使用绑定工作。问题是我们的linkwith.cs文件。使用上面的绑定和以下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)]
答案 2 :(得分:0)
对于遇到这个问题的其他人来说,这是值得的。我的问题是我的linkwith.cs文件没有包含LinkTarget.Simulator64。我得到类yyy的错误对象xxx没有实现methodSignatureForSelector: - 麻烦提前消息。