2012-07-17 3 views
1

저는 다음과 같은 objc 메소드를 가지고 있습니다.python callable을 "block"유형의 인수로 objc 메소드에 전달하는 방법

@ implementation of Class1 

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

} 

나는이 파이썬에서 방법을 실행 사용하려면, 내가 파이썬 목표 - 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) 
,536

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

나는 또한 람다 함수와 시도, 아무 소용이 :

파이썬은 같은 오류를 throw합니다.

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

하지만 파이썬 던져이 같은 오류 :

나는 또한 호출 가능한 클래스를 만들려고 내가 잘못 여기 짓을 어디

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

을 궁금?

+0

나는 오랫동안 이것을 사용하지 않았지만, '대신''이어야한다. 나는 당신의 문제를 해결할 것이라고 확신하지는 않습니다. 어떻게 메타 데이터를 생성 했습니까? –

+0

나는 실제로 귀하의 게시물 중 하나에 따라 데이터를 생성합니다. Apple 문서의 지시에 따라 사과 명령 줄 도구 gen_bridge_metadata를 사용하십시오. –

+0

블록 함수가 두 개가 아닌 하나의 인수를 취하면 함수가 호출된다는 것도 재미 있습니다. 하지만 어떻게 두 인수를 구별하는 ... –

답변

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'이면 블록으로 간주됩니다. if type = "#?" function_pointer = "true"이면 function_pointer로 해석됩니다. pyobjc가 이것을 왜 인식하지 못하는가? 이것은 pyobjc의 버그입니까?

+0

PyObjC가 PyObjC_processXML() 내부의 'switch'를 보면 Apple docs가 말하는 (function_pointer를 찾아야한다.) _ '[pyobjc-core/Modules/objc/parsexml.m] (http://svn.red-bean.com/pyobjc/trunk/pyobjc/pyobjc-core/Modules/objc/parsexml.m)에서, 이것에 대해서는 자세히 조사하지 않았다. PyObjC의 이전 버전을 사용하고 있습니까? –

+0

흠. 아마도. Mac OS에서 10.7.4의 Lion을 사용하고 있습니다. 비록 이것이 이것의 오래된 사본이라면 나는 확신하지 못한다. –

+0

충분히 최신 상태 여야합니다. 오, 그럼. 내가 다른 것을 알아 내면 다시 연락 할게. –

관련 문제