Получить аргумент массива объекта из NSInvocation с ARC

У меня есть метод со следующей подписью:

- (void)takeIntsAndRecieveIntsAsync:(MyInt *__strong [])
                         completion:(void (^)(MyInt * __strong response[]))success;

У меня была пара вопросов:

1. Как я могу получить аргумент, используя NSInvocation в этом методе?

- (void)forwardInvocation:(NSInvocation *)invocation

Я пробовал следующее, но не получил правильное значение:

__unsafe_unretained MyInt *a[2];
[invocation getArgument:(void *) &a atIndex:index];

У меня может быть массив из n int-объектов, поэтому я не должен жестко кодировать 2. Как определить размер массива объектов во время выполнения? Нужно ли значение часового в массиве для определения границ?

2. Корректен ли __strong для входного параметра и параметра блока? Обратите внимание, что блок является асинхронным и будет выполняться позже.

1 ответ

Решение

Ваш метод не принимает параметр массива - он принимает параметр указателя.

В C невозможно иметь параметр типа массива. Если вы напишите параметр типа "массив X", он автоматически изменится на тип "указатель на X".

Методы Objective-C - это функции C, но история немного другая. В последних версиях XCode, кажется, у вас могут быть параметры метода типа массива (хотя это, кажется, нигде не документировано). Но это должен быть конкретный тип массива, то есть с длиной, жестко закодированной во время компиляции:

- (void)takeIntsAndRecieveIntsAsync:(MyInt *__strong [5]);

Когда это неполный тип массива (например, MyInt *__strong []), он по-прежнему автоматически настраивается на указатель (например, MyInt *__strong *), значение является указателем на первый элемент массива.

  1. В C (и, следовательно, Objective-C) невозможно, учитывая указатель на первый элемент массива, сколько элементов имеет этот "массив". Вы должны каким-то образом получать эту информацию отдельно (будь то отдельный параметр длины, длина и указатель, упакованные вместе в какую-то структуру, значение "стража" в массиве и т. Д.).

  2. Он должен соответствовать типу массива, которому вы передаете указатель на первый элемент. Если это массив __strongто это должен быть указатель на __strongи т. д. Если ваша операция асинхронная, то вам, вероятно, нужно скопировать массив (для этого необходимо выяснить решение вопроса 1, как определить длину массива), чтобы ваша асинхронная операция имела сильные ссылки к тем MyInt объекты. Таким образом, ваша копия массива должна содержать __strong указатели.

Другие вопросы по тегам