Получить аргумент массива объектов из 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 как для входного параметра, так и для параметра блока? Обратите внимание, что блок является асинхронным и будет выполняться позже.


person pshah    schedule 22.04.2014    source источник
comment
Почему бы вам не использовать NSArray?   -  person michaels    schedule 22.04.2014
comment
Справедливый вопрос, но я хочу, чтобы API выражал, что ожидает массив объектов MyInt. NSArray позволит кому-то передавать любые объекты.   -  person pshah    schedule 22.04.2014
comment
я все еще могу передать любые объекты. просто используйте NSArray, чтобы облегчить себе жизнь.   -  person Bryan Chen    schedule 23.04.2014


Ответы (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 указателей.

person newacct    schedule 23.04.2014
comment
Большое спасибо! Это было очень полезно! - person pshah; 23.04.2014