Question

I have a method with the following signature:

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

I had a couple of questions:

1. How do I retrieve the argument using NSInvocation in this method?

- (void)forwardInvocation:(NSInvocation *)invocation

I tried the following but I don't get the correct value:

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

I can have an array of n int objects, so I should not hardcode 2. How do I determine the size of the object array at runtime? Do I need a sentinel value in the array to determine the bounds?

2. Is the __strong qualifier correct for both the input parameter and the block parameter? Please note that the block is asynchronous and would execute at a later time.

Was it helpful?

Solution

Your method does not take an array parameter -- it takes a pointer parameter.

In C, it's not possible to have a parameter of array type. If you write a parameter of type "array of X", it is automatically changed to type "pointer to X".

Objective-C methods are C functions, but the story is a little different. In recent versions of Xcode, it appears that you can have method parameters of array type (although this does not seem to be documented anywhere). But it must be a concrete array type, i.e. with a length hardcoded at compile-time:

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

When it's an incomplete array type (e.g. MyInt *__strong []), it is still automatically adjusted to a pointer (e.g. MyInt *__strong *), the value being a pointer to the first element of the array.

  1. In C (and thus Objective-C), it is not possible to know, given a pointer to the first element of an array, how many elements this "array" has. You must get this information separately somehow (whether it be a separate length parameter, the length and pointer packaged together in some kind of structure, a "sentinel" value in the array, etc.).

  2. It should match the type of the array you're passing the pointer to the first element of. If it's an array of __strong, then it needs to be pointer to __strong, etc. If your operation is asynchronous, then you probably need to copy the array (which requires you to figure out the solution to question 1, how to figure out the length of the array), so that your asynchronous operation will have strong references to those MyInt objects. Thus your copy of the array should contain __strong pointers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top