绑定的细节

来源:互联网 发布:奇门排盘软件下载 编辑:程序博客网 时间:2024/06/06 02:26

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

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


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


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

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


第三 查看下Obj-C 选择器的文档(译注1),为每一个你希望使用的选择器创建实例:

static Selector selInit       = new Selector("init");static Selector selAllObjects = new Selector("allObjects");static Selector selNextObject = new Selector("nextObject");


第四 你的类型需要提供构造函数。
你需要链接(chain)你的构造函数到基类的构造函数。【Export】属性将允许Obj-C代码通过指定的选择器名称来调用你的构造函数:
[Export("init")]public NSEnumerator()    : base(NSObjectFlag.Empty){    Handle = Messaging.IntPtr_objc_msgSend(this.Handle, selInit.Handle);}// 这个构造函数是必须的,这样Xamarin.iOS才能通过Obj-C代码来创建你的//类型的实例 public NSEnumerator(IntPtr handle)    : base(handle){}

第五 为你在第三步中声明的选择器提供方法实现。
在原生代码中,这步其实是在使用 objc_msgSend()来调用(invoke 译注2)选择器。注意使用Runtime.GetNSObject() 来转换IntPtr到恰当的NSObject类型(其子类)。如果想Obj-C代码能调用,方法必须声明为虚方法:
[Export("nextObject")]public virtual NSObject NextObject(){    return Runtime.GetNSObject(        Messaging.IntPtr_objc_msgSend(this.Handle, selNextObject.Handle));}// 注意这里的[Export]属性是修饰get/set 方法:public virtual NSArray AllObjects {    [Export("allObjects")]    get {        return (NSArray) Runtime.GetNSObject(            Messaging.IntPtr_objc_msgSend(this.Handle, selAllObjects.Handle));    }}


将之前代码合到一起:

namespace Example.Binding {    [Register("NSEnumerator")]    class NSEnumerator : NSObject    {        static Selector selInit       = new Selector("init");        static Selector selAllObjects = new Selector("allObjects");        static Selector selNextObject = new Selector("nextObject");        [Export("init")]        public NSEnumerator()            : base(NSObjectFlag.Empty)        {            Handle = Messaging.IntPtr_objc_msgSend(this.Handle,                selInit.Handle);        }        public NSEnumerator(IntPtr handle)            : base(handle)        {        }        [Export("nextObject")]        public virtual NSObject NextObject()        {            return Runtime.GetNSObject(                Messaging.IntPtr_objc_msgSend(this.Handle,                    selNextObject.Handle));        }        // Note that for properties, [Export] goes on the get/set method:        public virtual NSArray AllObjects {            [Export("allObjects")]            get {                return (NSArray) Runtime.GetNSObject(                    Messaging.IntPtr_objc_msgSend(this.Handle,                        selAllObjects.Handle));            }        }    }}


命令行绑定

你可以直接使用Xamarin.iOS的btouch-native(使用 bmac-native如果你是Xamarin.Mac)来生成你的绑定。这也是Xamarin Studio用来创建绑定的工具。
使用语法如下:
# Use this for Xamarin.iOS:bash$ /Developer/MonoTouch/usr/bin/btouch-native -e cocos2d.cs -s:enums.cs -x:extensions.cs# Use this for MonoMac: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官网 2015-11-2)
0 0
原创粉丝点击