Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you store functions in an array in Objective C?

I want to make an array of functions so that I could randomize the order in which these arrays happen. Could I do something like:

NSMutableArray *MyArray = [NSMutableArray arrayWithObjects: function1, function2, function3, nil];

So that if I could do something like this;

RandomNum = arc4random() %([MyArray count]);
MyArray[RandomNum];

Thus Randomizing the order in which these functions are called in? How do I store the functions in this array?

like image 724
Neil Shweky Avatar asked Feb 09 '14 14:02

Neil Shweky


3 Answers

As for ObjC blocks you can just store them in an NSArray directly. Plain C functions have to be wrapped into an NSValue:

NSArray *functions = @[[NSValue valueWithPointer:function1], [NSValue valueWithPointer:function2]];

Then you can call them as follow, just make sure you cast it to correct signature:

((void (*)(int))[functions[RandomNum] pointerValue])(10);
like image 188
Bartosz Ciechanowski Avatar answered Oct 06 '22 19:10

Bartosz Ciechanowski


There ways come to mind

  1. you can store blocks in an array
  2. but you can also method invocations there if you want to call methods and not blocks (you would do the latter via NSInvocation)
  3. For C functions, wrap them in an NSValue to store them and call em later

sample 1 -- blocks

    NSMutableArray *array = [NSMutableArray array];
    [array addObject:^{ /* block */ }];

sample 2 -- invocation

    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[object methodSignatureForSelector:selector]];
    invocation.target = object;
    invocation.selector = selector;
    [array addObject:invocation];

sample 3 -- C-Function

    [NSValue valueWithPointer:function1]
like image 42
Daij-Djan Avatar answered Oct 06 '22 20:10

Daij-Djan


Store a pointer to a function in an array and call the function:

#import <Foundation/Foundation.h>

static void hello() {
    NSLog(@"hey\n");
}

int main(int argc, char *argv[]) {
    @autoreleasepool {
        NSPointerArray *array = [NSPointerArray pointerArrayWithOptions:NSPointerFunctionsOpaqueMemory];
        [array addPointer: &hello];
        void* ptr = [array pointerAtIndex:0];
        ((void (*)(void)) ptr)(); // prints hey
    }
}
like image 1
Jano Avatar answered Oct 06 '22 20:10

Jano