I don't think it's possible to pass a stack-allocated array to NSTimer
(Objective-C is not very friendly to stack-allocated objects in general. You can pass a pointer to such an array, but NSTimer
can outlive almost all stacks in the application, and you may end up with a dangling pointer then) so you at least need to make this array static or global.
Then you can take a pointer to it, and wrap it with NSValue
like this:
static int data[array_rows][array_columns] = { { 0, 1, 2 }, { 3, 4, 5 } };
NSValue *userInfo = [NSValue valueWithPointer:&data];
Alternatively you can allocate the array in the dynamic memory:
int (*array)[array_columns] = malloc(array_rows * array_columns * sizeof(int));
if (array) {
int val = 0;
for (int i = 0; i < array_rows; ++i) {
for (int j = 0; j < array_columns; ++j) {
array[i][j] = val++;
}
}
}
NSValue *userInfo = [NSValue valueWithPointer:array];
As you already noticed, NSTimer
takes Objective-C classes as arguments, so NSValue
can be passed as is:
[NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(timerAction:)
userInfo:userInfo
repeats:YES];
Be advised that on the target side the array pointer looks somewhat different. For the static variable you need to dereference the pointer value:
- (void)timerAction: (NSTimer *)timer {
NSValue *userInfo = timer.userInfo;
int (*array)[array_columns] = *(int (**)[array_columns])userInfo.pointerValue;
...
And for the dynamic memory array it's already dereferenced:
- (void)timerAction: (NSTimer *)timer {
NSValue *userInfo = timer.userInfo;
int (*array)[array_columns] = userInfo.pointerValue;
...