2016-02-18 4 views
0

У меня странная проблема с извлечением аргумента из va_list, который отлично работает на симуляторе, проблема начинается, когда один и тот же код запускается на устройстве (iPhone 6s), похоже, что arm64 не поддерживает это , Есть идеи?Извлечение аргументов из va_list на arm64, Xcode

va_start(arguments, self_); 
id arg = va_arg(arguments, id); 
// arg is NULL 
va_end(arguments); 

Edit:

На тренажере получить правильный объект Arg (NSString *) Однако, когда тот же самый код запустить на устройстве (iPhone 6с) тот же объект, аргумент всегда NULL.

...^(id self_, SEL cmd_, ....) { 

..... 

va_list arguments; 
va_start(arguments, cmd_); 

NSUInteger arg_count = [methodSignature numberOfArguments]; 
for(NSUInteger i = 0; i < arg_count - 2; i++) { 

    NSUInteger idx = i+2; 
    const char *type = [methodSignature getArgumentTypeAtIndex:idx]; 

    if (strcmp(@encode(id), type) == 0) { 
     id arg = va_arg(arguments, id); 
     [invocation setArgument:&arg atIndex:idx]; 
    } 
} 
va_end(arguments); 
+1

Что такое 'id' ..? Какая странная проблема? Отправьте минимальный пример. – 2501

+0

Для минимального примера нам нужен и вызывающий; однако на основе этого 'if', я был бы склонен полагать, что вы можете пропустить аргументы. Имейте в виду, что vararg, передающий amd64, сильно отличается от x64, поэтому симулятор и аппаратное обеспечение - это мел и сыр. – Petesh

+0

доступ к тому же списку аргументов на симуляторе и устройстве arm7v, возвращает объект (тип id), иначе для iPhone 6s (arm64) это простой указатель, который вызывается при вызове invokeWithTarget – mbutan

ответ

0

Основной метод swizzled нестандартном блок, который обрабатывает новую реализацию, где в качестве аргумента проходящее: с переменным числом аргументов

void (*actionSelectorImplementationBlock) = ^(id self_, ...) { 
// ...... Creating Invocation etc.... 

va_list arguments; 
va_start(arguments, self_); 
NSUInteger arg_count = [methodSignature numberOfArguments]; 
for(NSUInteger i = 0; i < arg_count - 2; i++) { 

    NSUInteger idx = i+2; 
    const char *type = [methodSignature getArgumentTypeAtIndex:idx]; 

    id arg = va_arg(arguments, id); 
    [invocation setArgument:&arg atIndex:idx]; 
} 
va_end(arguments); 
// Invoke NSInvocatin 
} 

IMP newImplementation = imp_implementationWithBlock(actionSelectorImplementationBlock); 
method_setImplementation(originalMethod, newImplementation); 

Swizzled метод:

- (void)test:(NSNumber *)t test2:(NSString *)string; 
Смежные вопросы