Xamarin.ios绑定是如何实现的


绑定是怎样实现的--Xamarin.iOS

Xamarin.iOS


可以通过结合使用【Register】属性,【Export】属性,和手动调用Obj-C选择器来手动绑定新的Obj-C(之前未绑定过)类型。

第一 选一个你希望绑定的类型。

出于讨论的目的(及简便性),我们将选择绑定NSEnumerator 。(这个类型的绑定在Foundation.NSEnumerator中已经实现,以下对该类型的实现仅出于示例的目的)

第二 新建一个C#的类(类型)。

我们希望将这个类型置于某命名空间(namespace),由于Obj-C不支持命名空间,我们通过【Register】属性指定类型名称,Xamarin会注册到Obj-C运行时。
同样的,该C#类型需要继承Foundation.NSObject:

  1. namespace Example.Binding {
  2. [Register("NSEnumerator")]
  3. class NSEnumerator : NSObject
  4. {
  5. // see steps 3-5
  6. }
  7. }

第三 查看下Obj-C

选择器的文档(译注1),为每一个你希望使用的选择器创建实例:

  1. static Selector selInit = new Selector("init");
  2. static Selector selAllObjects = new Selector("allObjects");
  3. static Selector selNextObject = new Selector("nextObject");

第四 你的类型需要提供构造函数。

你需要链接(chain)你的构造函数到基类的构造函数。【Export】属性将允许Obj-C代码通过指定的选择器名称来调用你的构造函数:

第五 为你在第三步中声明的选择器提供方法实现。
在原生代码中,这步其实是在使用 objc_msgSend()来调用(invoke 译注2)选择器。注意使用Runtime.GetNSObject() 来转换IntPtr到恰当的NSObject类型(其子类)。如果想Obj-C代码能调用,方法必须声明为虚方法:

  1. [Export("nextObject")]
  2. public virtual NSObject NextObject()
  3. {
  4. return Runtime.GetNSObject(
  5. Messaging.IntPtr_objc_msgSend(this.Handle, selNextObject.Handle));
  6. }
  7. // 注意这里的[Export]属性是修饰get/set 方法:
  8. public virtual NSArray AllObjects {
  9. [Export("allObjects")]
  10. get {
  11. return (NSArray) Runtime.GetNSObject(
  12. Messaging.IntPtr_objc_msgSend(this.Handle, selAllObjects.Handle));
  13. }
  14. }

将之前代码合到一起:

  1. namespace Example.Binding {
  2. [Register("NSEnumerator")]
  3. class NSEnumerator : NSObject
  4. {
  5. static Selector selInit = new Selector("init");
  6. static Selector selAllObjects = new Selector("allObjects");
  7. static Selector selNextObject = new Selector("nextObject");
  8. [Export("init")]
  9. public NSEnumerator()
  10. : base(NSObjectFlag.Empty)
  11. {
  12. Handle = Messaging.IntPtr_objc_msgSend(this.Handle,
  13. selInit.Handle);
  14. }
  15. public NSEnumerator(IntPtr handle)
  16. : base(handle)
  17. {
  18. }
  19. [Export("nextObject")]
  20. public virtual NSObject NextObject()
  21. {
  22. return Runtime.GetNSObject(
  23. Messaging.IntPtr_objc_msgSend(this.Handle,
  24. selNextObject.Handle));
  25. }
  26. // Note that for properties, [Export] goes on the get/set method:
  27. public virtual NSArray AllObjects {
  28. [Export("allObjects")]
  29. get {
  30. return (NSArray) Runtime.GetNSObject(
  31. Messaging.IntPtr_objc_msgSend(this.Handle,
  32. selAllObjects.Handle));
  33. }
  34. }
  35. }
  36. }

命令行绑定

你可以直接使用Xamarin.iOS的btouch-native(使用 bmac-native如果你是Xamarin.Mac)来生成你的绑定。这也是Xamarin Studio用来创建绑定的工具。
使用语法如下:

  1. # Use this for Xamarin.iOS:
  2. bash$ /Developer/MonoTouch/usr/bin/btouch-native -e cocos2d.cs -s:enums.cs -x:extensions.cs
  3. # Use this for MonoMac:
  4. bash$ bmac-native -e cocos2d.cs -s:enums.cs -x:extensions.cs

上面的命令会在当前文件夹中成cocos2d.dll库文件,它包含完整的绑定,你可以在你的项目中使用。

  • 译注1:关于Obj-C的选择器,推荐一篇中文文章:Class类型,选择器Selector以及指针函数
  • 译注2:Obj-C中对Selector的调用,术语叫 send message,而非invoke selector,是通过objc_msgSend 一族函数完成。

(翻译自Xamarin官网)

作者:gt7466
原文地址:http://blog.csdn.net/gt7466/article/details/49585271

分享到