Pergunta

I have a objc method like this;

@ implementation of Class1

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

}

I want to use this execute method in python, i have build a python objective-c bridge data and it seems to be generated correctly as:

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

But when i define a function like this:

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

and try to use this as block

class1_obj.execute_(myFunc)

Python throw an errors as:

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

I also tried with lambda function, no use.

I also tried to create a callable class as:

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

but python throw an error like this:

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

I am wondering where did I do wrong here?

Foi útil?

Solução

Thanks for Josh's suggestion.

Finally got this problem solved. It looks like the meta_data generated by the system using command line gen_bridge_metadata somehow wasn't read correctly. It was generated as:

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

But after I change the function_pointer to block, it works. I got this by reading through pyobjc unit test for blocks.

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

I am not sure what causes this though. the Apple Doc says if type="@?" and function_pointer='true', it's regarded as block. if type = "#?" and function_pointer="true", it will interpreted as function_pointer. but why pyobjc can't recognize this? is this a bug in pyobjc?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top