#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]];