“Converting” a function pointer to a block in objective-C

后端 未结 3 2154
星月不相逢
星月不相逢 2021-02-20 07:48

I\'m doing some Interop from Mono C# to Obj-C and ran into this problem. The C# code needs to pass a callback - which it does with a function pointer. I can get the function poi

相关标签:
3条回答
  • 2021-02-20 08:24

    What about

    void (*myFunc)(int x); // ... your function pointer
    
    void (^myBlock)(int) = ^(int x) {
        myFunc(x);
    };
    

    Then myBlock is a block that captures the value of the function pointer and calls the function when the block is executed.


    ADDED: My suggestion, based on your code, using a @property (and assuming that you compile with ARC):

    FunctionToBlock.h:

    typedef void (*DummyAction)(char * result);
    typedef void (^DummyBlock)(char * result);
    
    @interface FunctionToBlock : NSObject
    {
        DummyAction function; // Not really needed.
    }
    
    - (id) initWithFunction: (DummyAction) func;
    @property(copy, nonatomic) DummyBlock block;   // "copy" is important here!
    
    @end
    

    FunctionToBlock.m:

    #import "FunctionToBlock.h"
    
    @implementation FunctionToBlock : NSObject
    @synthesize block = _block; // Can be ommitted if you use Xcode 4.4 or later.
    
    - (id) initWithFunction: (DummyAction) func
    {
        if (self = [super init]) {
            function = func; // Not really needed.
            self.block = ^(char * result) {
                func(result); // Use "func", not "self->function", to avoid retain cycle.
            };
        }
        return self;
    }
    
    0 讨论(0)
  • 2021-02-20 08:30

    A block is under the hood a pointer to a local data structure. A block becomes invalid as soon as you leave the scope where it was declared. The scope is the if-statement within init; as soon as you leave that, the block is invalid.

    You are breaking coding conventions here in a bad way. First, instance variables should start with an underscore, so that everyone sees what you are doing. Better to use properties without declaring instance variables at all. And every block property should be declared as "copy". If you do that, everything is fine.

    0 讨论(0)
  • 2021-02-20 08:34

    why not just have a simple function

    typedef void (*DummyAction)(char * result);
    typedef void (^DummyBlock)(char * result);
    
    DummyBlock functionToBlock(DummyAction func) {
        return [[^(char * result) {
                     func(result);
                 } copy] autorelease];
    }
    
    0 讨论(0)
提交回复
热议问题