Получить аргумент массива объекта из 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 *
), значение является указателем на первый элемент массива.
В C (и, следовательно, Objective-C) невозможно, учитывая указатель на первый элемент массива, сколько элементов имеет этот "массив". Вы должны каким-то образом получать эту информацию отдельно (будь то отдельный параметр длины, длина и указатель, упакованные вместе в какую-то структуру, значение "стража" в массиве и т. Д.).
Он должен соответствовать типу массива, которому вы передаете указатель на первый элемент. Если это массив
__strong
то это должен быть указатель на__strong
и т. д. Если ваша операция асинхронная, то вам, вероятно, нужно скопировать массив (для этого необходимо выяснить решение вопроса 1, как определить длину массива), чтобы ваша асинхронная операция имела сильные ссылки к темMyInt
объекты. Таким образом, ваша копия массива должна содержать__strong
указатели.