Добавление указателя функции в NSMutableArray

#ios #objective-c #xcode #nsmutablearray #selector

#iOS #objective-c #xcode #nsmutablearray #селектор

Вопрос:

Мне нужно добавить некоторые функции в NSMutableArray

Массив :

 [_array addObject:@selector(myFunction:)];
  

Функция :

 - (void) myFunction:(NSString*)someParam {}
  

Ошибка :

 Incompatible pointer types sending 'SEL' to parameter 'id'
  

Как я могу это сделать? :/

Цель состоит в том, чтобы вызывать функции массива случайным образом

С уважением

Комментарии:

1. @selector Не является «объектом» Cocoa.

2. Итак, как я могу добавить указатель функции в NSMutableArray ?

3. Создайте объект, содержащий селектор. Возможно, вы сможете использовать NSValue , но я подозреваю, что @selector это не простое значение указателя.

Ответ №1:

Вы можете хранить объекты только в NSArray. Но SEL не входит в их число (определяется как указатель на структуру в <objc/objc.h> ).

Чтобы сохранить ваш селектор в массиве, вам нужно будет упаковать его в NSValue объект, вот так:

 [_array addObject:[NSValue valueWithPointer:@selector(myFunction:)]];
  

Позже, когда вы действительно захотите использовать свой селектор, вам нужно будет распаковать его, вот так:

 SEL mySelector = [_array[0] pointerValue];

[target performSelector:mySelector];
  

Комментарии:

1. Не было бы проще просто вызвать NSStringFromSelector и просто сохранить строку?

2. Это сработало бы, но не стало бы проще (вам все равно придется конвертировать в строку и конвертировать из строки). Я больше склонен использовать NSValue решение, хотя оно больше похоже на то, что мы сохраняем тот же тип, просто помещая его в бокс.

3. @jlehr: Помещение указателя в значение NSValue и его извлечение — это O (1). Тогда как получение селектора из строки равно O (n).

Ответ №2:

Вы не можете добавить селектор в массив, поскольку SEL это не тип объекта.

Если вам нужно сохранить метод и параметры, вы можете создать NSInvocation объект и сохранить его в своем массиве.

Комментарии:

1. Или NSMethodSignature если аргументы не нужны.

2. @JoshCaswell: но тогда у него не будет имени метода

Ответ №3:

Другой альтернативой было бы использование блоков. Для функции

 -(void)myFunction{
}
  

Создайте блок, выполнив что-то вроде

 void (^CallingBlock)()=^(){
    [self myFunction];
};
  

Затем добавьте в массив как обычно

 NSMutableArray *array=[[NSMutableArray alloc] init];
[array addObject:CallingBlock];
  

Затем для выполнения блока

 [[NSOperationQueue mainQueue] addOperationWithBlock:[array objectAtIndex:0]];