PyObjC和自定义块

时间:2011-05-04 18:36:35

标签: cocoa macos pyobjc

官方文档说可以在python代码中使用自定义块,但是您需要创建元数据。我还没有找到它的一个例子。

我的问题是如何为自定义块创建,使用和分发元数据。

示例

@interface SomeClass

- (void)doSomethingWithCompletion: (void (^)(SomeObject *obj, NSError *error))myBlock;

@end


def pythonMethod():
    def completion(obj, error):
        # staff
    foo = SomeClass.new()
    foo.doSomethingWithCompletion_(somehow_pass_completion)

问题是somehow_pass_completion的外观以及如何为myBlock提供元数据。

1 个答案:

答案 0 :(得分:6)

提到的元数据是以XML格式存储的有关Objective-C方法的返回和参数类型的信息。需要这样才能使PyObjC桥知道在将Python对象传回Objective-C代码时将其转换为什么类型。如果您愿意,可以查看元数据;它位于PyObjC框架内的.bridgesupport文件中。例如,AppKit元数据位于/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/PyObjC/AppKit/PyObjC.bridgesupport可以为您使用的任何Objective-C代码生成它Apple的gen_bridge_metadata命令行工具。该实用程序有man page,而man 5 BridgeSupport也提供了信息。 1

PyObjC提供函数objc.registerMetaDataForSelectorobjc.parseBridgeSupport,这两个函数都允许您使用Python dicts(前一个函数)或BridgeSupport手册页中描述的XML格式为您的方法添加元数据(后者)。 pyobjc源代码中提供了使用registerMetaData...的示例:pyobjc/pyobjc-core/PyObjCTest/test_metadata*(及附近的test_metadata*.py个文件) 2

就像一个例子,这是-[NSSavePanel beginWithCompletionHandler:]的元数据,它以块作为参数:

<method selector='beginWithCompletionHandler:'>
    <arg index='0' block='true' >
        <retval type='v' />
        <arg type='i' type64='q' />
    </arg>
</method>

arg类型说明符与您在Obj-C中使用@encode时获得的Type Encodings相同。您的方法的元数据应该非常相似。

因此,既然您已经在Objective-C中使用了原型方法,那么您应该能够通过gen_bridge_metadata运行它们来创建可以包含在项目中的.bridgesupport文件,然后使用objc.parseBridgeSupport读取该文件。使用objc.registerMetaDataForSelector过去也对我有用;看看上面链接的例子。

在PyObjC“系统”中获得元数据后,您可以使用任何旧的可调用对象作为获取块的方法的参数:

def pythonMethod():
    def myCompletionHandler(obj, error):
        pass
foo = SomeClass.new()
foo.doSomethingWithCompletion_(myCompletionHandler)

这是我在这里发表的关于PyObjC的一些其他帖子的混合物:PyObjC and Returning Out Parameters | Indexed Accessor Method | Problem with openPanelDidEnd。您可能也想看看这些。

我已经有一段时间了,所以我可能已经遗漏了一些东西。如果您仍然无法使用此功能,请随时询问更多信息。不要轻易放弃 - 桥梁是一个有趣的野兽,有时你只需要告诉它谁是老板!


1 您应阅读的另一个Apple文档是:Generating Framework Metadata
2 我通过pyobjc-dev mailing list thread发现了这些