Форум программистов, компьютерный форум CyberForum.ru

Вызов блока с переменными параметрами - Objective-C

Восстановить пароль Регистрация
 
dontgiveafk
36 / 16 / 0
Регистрация: 29.01.2010
Сообщений: 252
19.02.2015, 11:37     Вызов блока с переменными параметрами #1
Странное дело. Есть функция/метод у объекта:
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
-(void) BlockCall:(void (^)(float a, float b, NSObject *object, NSObject *secObject, NSObject *thirdObject)) argBlock
                withObject: (NSObject *)object
                   andSObj:(NSObject *)sobject
                   andTObj:(NSObject *)tobject
{
 
    object = [[NSObject alloc] init];
    sobject = [[NSObject alloc] init];
    tobject = [[NSObject alloc] init];
    NSLog(@"First object:%@", object);
    NSLog(@"Second object:%@", sobject);
    NSLog(@"Third object:%@", tobject);
    argBlock(15 ,27, object, sobject, tobject);
}
И блок :
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
void (^voidBlock)(va_list args, ...);
  voidBlock= ^(va_list args, ...){
 
      va_list parsArgs;
      va_start(parsArgs, args);
 
        va_arg(parsArgs, double);
        va_arg(parsArgs, double);
        id NSObjectArg = va_arg(parsArgs, id);
        id NSObjectArg2 = va_arg(parsArgs, id);
        id NSObjectArg3 = va_arg(parsArgs, id);
     va_end(parsArgs); 
 }
Если я вызову эту функцию с корректными параметрами и передам ей блок в качестве параметра, то внутри блока он корректно прочитает два первых флота потом второй переданный объект он прочитает как первый NSObjectArg, третий прочитает как NSObjectArg2.
И так всегда он будет читать все примитивы до первого указателя, потом сожрет первый указатель и прочитает все остальные.
Если блок изменить и сделать его с фиксированными параметрами то все он нормально прочитает, но мне нужен именно блок с переменными параметрами
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.02.2015, 11:37     Вызов блока с переменными параметрами
Посмотрите здесь:

Процедура с параметрами переменными Pascal
Подпрограммы с типизированными параметрами -значениями и параметрами-переменными Pascal
Запуск метода с параметрами в новом потоке Objective-C
Objective-C Указатель на функцию с параметрами
Вызов метода Obj-C Objective-C
Objective-C Вызов объекта в keyDown
Подпрограммы с типизированными параметрами -значениями и параметрами-переменными Turbo Pascal
Вызов метода с возвратом значения Objective-C
Вызов метода из другого класса Objective-C
Вызов метода базового класса, если он был переопределён в наследнике Objective-C
Вызов функции после некоторого времени Objective-C
Node.js Вызов скрипта с параметрами скрипта рекурсивно с своими глобальными переменными каждый вызов

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
zulkis
 Аватар для zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
19.02.2015, 11:56     Вызов блока с переменными параметрами #2
dontgiveafk, дело простое, не странное.
Читайте https://developer.apple.com/library/...itChanges.html
Дело в разном размере float и pointer в 64-битной системе.
Вы можете изменить float -> CGFloat, что должно вылечить симптом. Но я бы на вашем месте пересмотрел взгляд на использование таких блоков.
Другое, более верное решение - передавать список с указателями на объекты, и использовать не примитивы, но NSNumber.

С другой стороны - я не могу с уверенностью сказать что сделает LLVM с типом float в списке. По стандарту вроде должен преобразовать в double, а это уже 8. Если все так - то проблема может быть не там, где я подумал.
dontgiveafk
36 / 16 / 0
Регистрация: 29.01.2010
Сообщений: 252
19.02.2015, 15:01  [ТС]     Вызов блока с переменными параметрами #3
CGFloat не лечит симптом, если посмотреть этот тип, там все промотится до double и поведение такое же, отсюда другой вопрос:
Я хочу сам вычислить смещение и читать эти аргументы ? задавая сам сколько байт нужно прочитать могу ли я как ни это сделать?

Добавлено через 24 минуты
То есть я не хочу писать float b = va_arg(parsArgs, double) , а хочу написать float b = va_arg(parsArgs, 8) считай мне 8 следующих байт и интерпретируй как float или хочу написать float b = va_arg(parsArgs, sizeof(double)/alignof(float))
считай мне результат этого деления и интерпретируй как флотб или двигать его как pointer

Добавлено через 1 час 36 минут
Если блок будет принимать два int и шагать в va_arg по int то проблема та же следующий за int ссыльный тип сотрется
zulkis
 Аватар для zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
19.02.2015, 19:40     Вызов блока с переменными параметрами #4
va_list вообще не создавался для того, чтобы разные типы гонять в нем.
Гарантий, что ваша арифметика заведется на другой архитектуре(читайте ARM/x64/x86) - нет никаких.
Есть замечательный ответ на SO по этому поводу.
Вся эта затея очень шаткая, скажите - зачем вам это? Наверняка есть более простые способы...
Yandex
Объявления
19.02.2015, 19:40     Вызов блока с переменными параметрами
Ответ Создать тему
Опции темы

Текущее время: 07:14. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru