绑定的细节

绑定是怎样实现的--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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值