Search code examples
iphoneobjective-ccocoansinvocationperformselector

NSInvocation pass C-arrays to Objective-C method


I want to pass C-arrays to a method in Objective-C after a delay. Typically I could performSelector:withObject:afterDelay but I can't change the arrays in any way or convert them to NSMutableArrays, NSDictionaries or any other Cocoa object - they need to be C Arrays. In my research here on StackOverflow and Google I've found that one way to pass a C primitive is to wrap them in an NSInvocation. I've tried doing this with the code below and setting the arguments as pointers to the arrays being passed.

float gun1_vertex[24][8] = { {data,...data},{data,...data}, ... {data,...data} };
float gunDown1_vertex[24][8] = { {data,...data},{data,...data}, ... {data,...data} };

NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(testMethod:secondCArray:)]];
  [inv setSelector:@selector(testMethod:secondCArray:)];
  [inv setTarget:self];
  [inv setArgument:&gun1_vertex[0][0] atIndex:2];
  [inv setArgument:&gunDown1_vertex[0][0] atIndex:3];
  [inv performSelector:@selector(invoke) withObject:nil afterDelay:0.1f];

My test app keeps crashing when I attempt to print a few of the values from the passed arrays in the method below. I'm probably just missing something completely obvious. Can somebody please shed some light here?

- (void)testMethod:(float *)test secondCArray:(float *)test2 {

    for ( int a = 0 ; a < 10 ; a++ ) {

        NSLog(@"%f %f",test[a],test2[a]);

    }

}

Solution

  • You could do something like this:

    -(void) testMethod:(NSData *) arrayone secondArray:(NSData *) arraytwo
    {
        float **gun1_vertex = (float **)[arrayone bytes];
        float **gunDown1_vertex = (float **)[arraytwo bytes];
    
        // ...
    }
    
    NSData *gun1data = [NSData dataWithBytes:(void *)gun1_vertex     length:sizeof(float) * 24 * 8];
    NSData *gun1downData = [NSData dataWithBytes:(void *)gunDown1_vertex length:sizeof(float) * 24 * 8];
    
    [inv setArgument:&gun1data atIndex:2];
    [inv setArgument:&gun1downData atIndex:3];