Reputation: 50
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]);
}
}
Upvotes: 2
Views: 548
Reputation: 53000
Your problem is not enough indirection. setArgument
takes a pointer to the location of the value you wish to set as the argument, and the value in your case is also a pointer... Using the passed pointer and the type information setArgument
can copy the correct number of bytes.
So you need something like:
float *gun1_vertex_pointer = &gun1_vertex[0][0];
[inv setArgument:&gun1_vertex_pointer atIndex:2];
Upvotes: 3
Reputation: 55543
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];
Upvotes: 3
Reputation: 3184
To make the call after a delay, use dispatch_after
block:
double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self testMethod:&gun1_vertex[0][0] secondCArray:&gunDown1_vertex[0][0]];
});
Upvotes: 1