The IMP
type in Objective-C represents a function pointer, as far I as understand. Is there any way to make an IMP
from a block pointer? Thanks for your ideas.
相关问题
- CALayer - backgroundColor flipped?
- Core Data lightweight migration crashes after App
- back button text does not change
- iOS (objective-c) compression_decode_buffer() retu
- how to find the index position of the ARRAY Where
相关文章
- 现在使用swift开发ios应用好还是swift?
- TCC __TCCAccessRequest_block_invoke
- xcode 4 garbage collection removed?
- Unable to process app at this time due to a genera
- How can I add media attachments to my push notific
- didBeginContact:(SKPhysicsContact *)contact not in
- Custom Marker performance iOS, crash with result “
- Converting (u)int64_t to NSNumbers
I believe Mike Ash, with some help from Landon Fuller, has solved this for the general case, including iOS, which is harder. He has a class on github which will turn a block into a function pointer.
You may also want to confer the announcement and some interesting follow-up discussion on cocoa-unbound.
UPDATE: And now there's
imp_implementationWithBlock()
as referred above.Since this was written there is now API in iOS and Mac OS X that allows Blocks to be turned into IMPs directly. I wrote up a weblog post describing the API (imp_implementationWithBlock()).
A block is effectively a structure that contains a bit of metadata, a reference to the code contained within the block and a copy of the const-copied data captured within the block.
Thus, no, there is no way to directly map between an
IMP
and a Block reference.When a call to a block is compiled, the compiler emits a trampoline that sets up the stack frame and then jumps to the executable code within the block.
What you can do, though, is create an IMP that acts like that trampoline. For the following, you will need one specific IMP for each set of arguments & return types to be called. If you need to make this generic, you'll need to use assembly.
For this, I'm setting up unique block instances per instance of the class. If you want to have a generic block that acts across all instances, build a hash of
SEL
-> block per class.(1) Associate blocks to act as IMPs using the associated references mechanism. Something like:
(2) implement a trampoline IMP something like this:
(3) stuff the above trampoline in for any selector via the Objective-C runtime's API (see
method_setImplementation
and like)Caveats:
this was typed into StackOverflow. The real code will be similar, but likely slightly different.
the [implementingBlock copy] is critical; Blocks start life on the stack (usually)