В MyClass.m я определил
- (void) myTest: (NSString *) withAString{
NSLog(@"hi, %@", withAString);
}
и соответствующее объявление в MyClass.h. Позже я хочу позвонить
[self performSelector:@selector(mytest:withAString:) withObject: mystring];
в MyClass.m, но я получаю сообщение об ошибке, похожее на * Завершение работы приложения из-за неперехваченного исключения 'NSInvalidArgumentException', причина: '* - [MyClass myTest: withAtring:]: нераспознанный селектор отправлен в экземпляр 0xe421f0'
Я попробовал более простой случай с селектором, который не принимал аргументов, выводил строку на консоль и работал нормально. Что не так с кодом и как это исправить? Спасибо.
Ответы:
Подпись вашего метода:
- (void) myTest:(NSString *)
withAString является параметром (имя вводит в заблуждение, похоже, что это часть сигнатуры селектора).
Если вы вызываете функцию таким образом:
[self performSelector:@selector(myTest:) withObject:myString];
Это будет работать.
Но, как предлагали другие плакаты, вы можете переименовать метод:
- (void)myTestWithAString:(NSString*)aString;
И звоните:
[self performSelector:@selector(myTestWithAString:) withObject:myString];
источник
В Objective-C сигнатура селектора состоит из:
Селекторы не знают:
Вот реализация класса, в которой метод performMethodsViaSelectors выполняет другие методы класса посредством селекторов:
@implementation ClassForSelectors - (void) fooNoInputs { NSLog(@"Does nothing"); } - (void) fooOneIput:(NSString*) first { NSLog(@"Logs %@", first); } - (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second { NSLog(@"Logs %@ then %@", first, second); } - (void) performMethodsViaSelectors { [self performSelector:@selector(fooNoInputs)]; [self performSelector:@selector(fooOneInput:) withObject:@"first"]; [self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second"]; } @end
Метод, для которого вы хотите создать селектор, имеет один вход, поэтому вы должны создать селектор для него следующим образом:
SEL myTestSelector = @selector(myTest:);
источник
@Shane Arney
Вы также можете упомянуть, что этот метод предназначен только для передачи максимум 2 аргументов и его нельзя отложить. (например
performSelector:withObject:afterDelay:)
.как-то странно, что яблоко поддерживает отправку только двух объектов и не делает его более общим.
источник
У вашего кода две проблемы. Один был идентифицирован и ответил, а другой - нет. Во-первых, в вашем селекторе отсутствовало имя параметра. Однако даже когда вы это исправите, строка все равно вызовет исключение, если ваша измененная сигнатура метода все еще включает более одного аргумента. Допустим, ваш измененный метод объявлен как:
-(void)myTestWithString:(NSString *)sourceString comparedTo:(NSString *)testString ;
Создание селекторов для методов, которые принимают несколько аргументов, совершенно допустимо (например, @selector (myTestWithString: compareTo :)). Однако метод performSelector позволяет передавать в myTest только одно значение, которое, к сожалению, имеет более одного параметра. Он выдаст ошибку и сообщит, что вы не предоставили достаточно значений.
Вы всегда можете переопределить свой метод, чтобы получить коллекцию как единственный параметр:
-(void)myTestWithObjects:(NSDictionary *)testObjects ;
Однако есть более элегантное решение (не требующее рефакторинга). Ответ заключается в использовании NSInvocation, наряду с его
setArgument:atIndex:
иinvoke
методами.Я написал статью, включая пример кода , если вам нужны подробности. Основное внимание уделяется многопоточности, но основы все еще применимы.
Удачи!
источник
Сигнатура вашего метода не имеет смысла, вы уверены, что это не опечатка? Я не понимаю, как он вообще компилируется, хотя, возможно, вы получаете предупреждения, которые игнорируете?
Сколько параметров вы ожидаете от этого метода?
источник
Думаю, класс следует определить как:
- (void) myTestWithSomeString:(NSString *) astring{ NSLog(@"hi, %s", astring); }
У вас есть только один параметр, поэтому у вас должен быть только один:
Возможно, вы захотите также рассмотреть возможность использования% @ в вашем NSLog - это просто хорошая привычка - затем будет записывать любой объект, а не только строки.
источник
В документе Apple говорится, что для этой функции и некоторых других ожидаемых функций на настраиваемой клавиатуре нет API. поэтому вам нужно выяснить свою собственную логику, чтобы реализовать это.
источник