2012-07-17 38 views
1

我有一個像這樣的objc方法;如何將python callable作爲「block」類型的參數傳遞給objc方法

@ implementation of Class1 

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

} 

我想用這個在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> 

我也試圖與lambda函數,沒有用。

我還試圖創建一個可調用的類爲:

>>> 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 

我不知道在哪裏我錯在這裏做什麼?

+0

我很久沒有使用過這個函數了,但是我記得,''應該改爲''。不過,我一點也不確定這會解決你的問題。你是如何生成這些元數據的? – 2012-07-17 23:36:01

+0

我根據你的帖子實際生成數據。根據apple文檔的指示使用apple命令行工具gen_bridge_metadata。 – 2012-07-17 23:44:25

+0

這也是有趣的,如果我設置塊函數需要一個參數而不是兩個,函數將被調用。但如何區分這兩個參數... – 2012-07-17 23:45:17

回答

2

感謝喬希的建議。

終於解決了這個問題。它看起來像是由系統使用命令行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阻止後,它的工作原理。我通過閱讀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中的錯誤?

+0

像PyObjC這樣的_seems_正在做蘋果文檔應該說的東西(查找「function_pointer」),如果你看看PyObjC_processXML() '[pyobjc-core/Modules/objc/parsexml.m](http://svn.red-bean.com/pyobjc/trunk/pyobjc/pyobjc-core/Modules/objc/parsexml.m),但我仍然沒有詳細檢查這一點。你可能使用PyObjC的舊版本? – 2012-07-23 19:46:10

+0

hmm。也許。我使用的是Mac OS上的Lion 10.7.4。我不確定這是否是它的舊版本。 – 2012-07-24 18:03:17

+0

這應該是足夠新的。好吧。如果我想出其他的東西,我會回到你身邊。 – 2012-07-24 18:03:58

相關問題