NSInvocation передать C-массивы в метод Objective-C - PullRequest
2 голосов
/ 31 января 2012

Я хочу передать C-массивы методу в Objective-C после задержки. Обычно я мог бы выполнитьSelector: withObject: afterDelay, но я не могу каким-либо образом изменить массивы или преобразовать их в NSMutableArrays, NSDictionaries или любой другой объект Какао - они должны быть массивами C. В моем исследовании StackOverflow и Google я обнаружил, что один из способов передать примитив C - это обернуть их в NSInvocation. Я попытался сделать это с помощью приведенного ниже кода и установить аргументы в качестве указателей на передаваемые массивы.

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];

Мое тестовое приложение продолжает падать, когда я пытаюсь распечатать несколько значений из переданных массивов в методе ниже. Я, наверное, просто упускаю что-то совершенно очевидное. Может кто-нибудь, пожалуйста, пролить свет здесь?

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

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

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

    }

}

Ответы [ 3 ]

3 голосов
/ 31 января 2012

Вы можете сделать что-то вроде этого:

-(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];
3 голосов
/ 31 января 2012

У вашей проблемы недостаточно косвенного обращения.setArgument принимает указатель на местоположение значения, которое вы хотите установить в качестве аргумента, и значение в вашем случае также является указателем ... Использование переданного указателя и информации о типе setArgumentможно скопировать правильное количество байтов.

Так что вам нужно что-то вроде:

float *gun1_vertex_pointer = &gun1_vertex[0][0];
[inv setArgument:&gun1_vertex_pointer atIndex:2];
1 голос
/ 31 января 2012

Чтобы сделать звонок после задержки, используйте 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]];
    });
...