带有范围的pyobjc索引访问器方法

我正在尝试按照the KVC guide在Python中为我的模型类实现索引访问器方法.出于性能原因,我想使用可选的ranged方法来一次加载多个对象.该方法使用一个指向C数组缓冲区的指针,我的方法需要将该对象复制到C数组缓冲区中.我已经尝试过类似以下的方法,但无法正常工作.我该如何完成?

@objc.accessor    # i've also tried @objc.signature('v@:o^@')
def getFoos_range_(self, range):
    return self._some_array[range.location:range.location + range.length]

编辑:苹果移动了所有文档之后,我终于找到了type encodings reference.看完之后,我尝试了一下:

@objc.signature('v@:N^@@')
def getFoos_range_(self, buf, range):

但这似乎也不起作用.第一个参数应该是指向C数组的指针,但是长度在运行时之前是未知的,所以我不知道如何构造正确的类型编码.我试过’v @:N ^ [1000 @] @’只是想看看,但是那也不起作用.

我的模型对象绑定到驱动表视图的NSArrayController的contentArray上.它似乎根本没有调用此方法,可能是因为它期望与网桥提供的签名不同的签名.有什么建议么?

解决方法:

你近了此方法的正确装饰器是:

@objc.signature('v@:o^@{_NSRange=QQ}')

NSRange不是对象,而是结构,不能简单地指定为@;您需要包括成员1.

不幸的是,这还没有结束.经过大量的实验和对PyObjC源代码的研究,我终于弄清楚了,为了使此方法起作用,您还需要为该签名指定多余的元数据. (但是,我仍然不知道为什么.)

这可以通过使用objc.registerMetaDataForSelector函数来完成:

objc.registerMetaDataForSelector(b"SUPERCLASSNAME", 
                                 b"getKey:range:",
        dict(retval=dict(type=objc._C_VOID),
             arguments={ 
                  2+0:  dict(type_modifier=objc._C_OUT,
                             c_array_length_in_arg=2+1),
                  2+1:  dict(type=b'{_NSRange=II}',
                             type64=b'{_NSRange=QQ}')
             }
        )
)

在PyObjC源代码的文件test_metadata_py.py(和附近的test_metadata * .py文件)中可以找到使用此功能的示例和一些详细信息.

注:必须在要实现get< Key:gt:range:for的任何类的超类上指定元数据,并且还需要在类定义结束之前的某个时候调用此函数(但必须在类定义之前或内部)类语句本身似乎都可以工作).我也没有弄清楚这些内容. 我将此元数据基于Foundation PyObjC.bridgesupport文件2中NSArray getObjects:range:的元数据,并通过参考Apple的BridgeSupport manpage得到了帮助.

有了这个解决方案,还值得注意的是定义该方法的最简单方法是(至少是IMO):

@objc.signature('v@:o^@{_NSRange=QQ}')
def get<#Key#>_range_(self, buf, inRange):
    #NSLog(u"get<#Key#>")
    return self.<#Key#>.getObjects_range_(buf, inRange)

即,使用数组的内置getObjects:range:.

1:在32位Python上,QQ(意味着两个无符号的long long)应该变成II,意味着两个无符号的int
2 :(在Snow Leopard上)位于:/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/PyObjC/Foundation/PyObjC.bridgesupport

上一篇:从C使用NSProcessInfo


下一篇:使用Python在Mac OS X中查找当前活动窗口