1

私はこのようなobjcメソッドを持っています。

@ implementation of Class1

- (void)execute:(void (^)(Class2* target, NSUInteger idx))block
{
... 

}

このexecuteメソッドをPythonで使用したいのですが、PythonのObjective-Cブリッジデータを作成しましたが、次のように正しく生成されているようです。

<class name='Class1'>
<method selector='execute:'>
<arg function_pointer='true' type='@?' index='0'>
    <arg type='@'/>
    <arg type='I' type64='Q'/>
    <retval type='v'/>
</arg>
</method>

しかし、私がこのような関数を定義すると:

def myFunc (dev, index):
    // do something with dev
    print("Hello")

これをブロックとして使用してみてください

class1_obj.execute_(myFunc)

Pythonは次のようにエラーをスローします:

objc.BadPrototypeError: Objective-C expects 1 arguments, Python argument has 2 arguments for <unbound selector myFunc at 0x105b3a3f0>

ラムダ関数も試してみましたが、無駄です。

また、呼び出し可能なクラスを次のように作成しようとしました。

>>> class myCallable(object):
...     def __init__(self,name):
...             print "Init"
...     def __repr__(self):
...             return "string init"
...     def __call__(self, dev, index):
...             # do something with dev
...             print("hello")

しかし、Pythonは次のようなエラーをスローします:

TypeError: Sorry, cannot create IMP for instances of type myCallable

私はここでどこを間違えたのだろうか?

4

1 に答える 1

2

Joshの提案に感謝します。

ついにこの問題は解決されました。コマンドラインgen_bridge_metadataを使用してシステムによって生成されたmeta_dataが、どういうわけか正しく読み取られなかったようです。次のように生成されました:

<method selector='execute:'>
<arg index='0' type='@?' function_pointer='true'>
<arg type='@'/>
<arg type64='Q' type='I'/>
<retval type='v'/>
</arg>
</method>

しかし、function_pointerをblockに変更すると、機能します。これは、ブロックのpyobjcユニットテストを読んで取得しました。

<method selector='execute:'>
<arg index='0' type='@?' block='true'>
<arg type='@'/>
<arg type64='Q' type='I'/>
<retval type='v'/>
</arg>
</method>

何が原因なのかわかりませんが。Apple Docは、type = "@?" そしてfunction_pointer='true'、それはブロックと見なされます。type = "#?"の場合 そしてfunction_pointer="true"、それはfunction_pointerとして解釈されます。しかし、なぜpyobjcはこれを認識できないのですか?これはpyobjcのバグですか?

于 2012-07-19T04:09:09.853 に答える