我正在实现一个 ObjC 协议作为 PyObjC 类的混合。
该协议定义了一个“out”参数。
我找不到任何关于实现定义它的 ObjC 协议的 Python 类的行为的好的文档。
我找到了这个邮件列表线程,但那里的建议不起作用。他们说返回一个 Python 列表,其中方法的返回值作为第一项,输出参数作为第二项。
我试过这个,我得到的只是从 ObjC ( <type 'exceptions.ValueError'>: depythonifying 'char', got 'tuple')调用时的一个例外。
似乎 PyObjC 在 depythonifying 方法参数中严格遵守 ObjC 协议,这很好,但它并没有帮助我尝试修改输出参数。
这是 ObjC 协议:
#import <Foundation/Foundation.h>
@protocol TestProtocol <NSObject>
- (BOOL)testMethod:(NSError **)error;
@end
Run Code Online (Sandbox Code Playgroud)
这是实现此协议的 Python 类:
from Foundation import *
import objc
NSObject = objc.lookUpClass("NSObject")
TestProtocol = objc.protocolNamed("TestProtocol")
class TestClass(NSObject, TestProtocol):
def testMethod_(self, error):
return True, None
Run Code Online (Sandbox Code Playgroud)
问题:如何在 Python 中返回 ObjC 输出参数?
这个问题很老了,所以不知道你现在是否已经解决了它,但是你还没有回答它,不久前我正在忙于从Obj-C获取参数到Python。有几件事你绝对应该尝试/研究:
首先也是最简单的是:当你在 Objective-C 中使用 Python 实现创建存根时,你必须指定(NSError **)is 一个out参数:
@interface MyObject : NSObject
- (BOOL)testMethod:(out NSError **)error;
@end
Run Code Online (Sandbox Code Playgroud)
我已经成功地使用它从 Python 调用自定义 Obj-C 方法。我相信 Python 方面不会获得正确的元数据。
还signature为您的 Python 方法定义添加了一个装饰器。您可以指定其中一个参数是 sig 中的输出参数。这个PyObjC 文档提供了详细信息。
@objc.signature('@@:io^@')
Run Code Online (Sandbox Code Playgroud)
另一件事是(你现在可能已经自己弄清楚了)如果你不想做 Objective-C 存根,你可以生成你自己的元数据并将 .bridgesupport 文件粘贴到你的项目。我不确定的唯一事情(最重要的事情!)是如何确保该文件确实被读取。元数据本身真的很容易编写——Apple 提供了一个名为 gen_bridge_metadata 的命令行实用程序,您可以手动完成(查看 /System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python /PyObjC/AppKit/PyObjC.bridgesupport)。该实用程序有一个手册页,并且man 5 BridgeSupport内容丰富。您应该阅读的另一个 Apple 文档是:生成框架元数据。
对未来读者的更新:我找到了函数objc.registerMetaDataForSelector和objc.parseBridgeSupport,这两个函数都允许您使用 Python dicts(前一个函数)或 BridgeSupport 手册页(后一个)中描述的 XML 格式为您的方法添加元数据。使用示例registerMetaData...可在 pyobjc 源中找到:pyobjc/pyobjc-core/PyObjCTest/test_metadata*,我是通过这个 pyobjc-dev mailing list thread 发现的。