Objective-C: вызов селекторов с несколькими аргументами

139
задан Stu 19 June 2009 в 18:56
поделиться

5 ответов

Сигнатура вашего метода:

- (void) myTest:(NSString *)

withAString является параметром (имя вводит в заблуждение, похоже, что это часть сигнатуры селектора).

Если вы вызываете функцию таким образом:

[self performSelector:@selector(myTest:) withObject:myString];

Это будет работать.

Но, как предлагали другие плакаты, вы можете переименовать метод:

- (void)myTestWithAString:(NSString*)aString;

И позвонить:

[self performSelector:@selector(myTestWithAString:) withObject:myString];
135
ответ дан 23 November 2019 в 23:16
поделиться

В Objective-C сигнатура селектора состоит из:

  1. имени метода (в данном случае это будет 'myTest') (обязательно)
  2. A ':' (двоеточие) после имени метода, если метод имеет ввод.
  3. Имя и ':' для каждого дополнительного ввода.

Селекторы не знают:

  1. Типы ввода
  2. Тип возвращаемого значения метода .

Вот реализация класса, в которой метод 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:);
311
ответ дан 23 November 2019 в 23:16
поделиться

Ваша подпись метода не имеет смысла, вы уверены, что это не опечатка? Я не понимаю, как он вообще компилируется, хотя, возможно, вы получаете предупреждения, которые игнорируете?

Сколько параметров вы ожидаете от этого метода?

3
ответ дан 23 November 2019 в 23:16
поделиться

Считаете, что класс должен быть определен как:

- (void) myTestWithSomeString:(NSString *) astring{
    NSLog(@"hi, %s", astring);
}

У вас есть только один параметр, поэтому вы должны иметь только один:

Вы также можете рассмотреть возможность использования% @ в вашем NSLog - это просто хорошая привычка - затем вы будете записывать любой объект, а не только строки.

2
ответ дан 23 November 2019 в 23:16
поделиться

У вашего кода две проблемы. Один был идентифицирован и ответил, а другой нет. Во-первых, в вашем селекторе отсутствовало имя параметра. Однако даже когда вы это исправите, строка все равно вызовет исключение, если ваша измененная подпись метода все еще включает более одного аргумента. Допустим, ваш измененный метод объявлен как:

-(void)myTestWithString:(NSString *)sourceString comparedTo:(NSString *)testString ;

Создание селекторов для методов, которые принимают несколько аргументов, совершенно допустимо (например, @selector (myTestWithString: compareTo :)). Однако метод performSelector позволяет передавать в myTest только одно значение, которое, к сожалению, имеет более одного параметра. Он выдаст ошибку и сообщит вам, что вы не предоставили достаточно значений.

Вы всегда можете переопределить свой метод, чтобы принимать коллекцию как единственный параметр:

-(void)myTestWithObjects:(NSDictionary *)testObjects ;

Однако, есть более элегантное решение (не требующее рефакторинга). Ответ - использовать NSInvocation вместе с его setArgument: atIndex: и вызывать методы .

Я написал статью, включая пример кода ], если вам нужны подробности. Основное внимание уделяется многопоточности, но основы все еще применимы.

Удачи!

7
ответ дан 23 November 2019 в 23:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: