Когда использовать двоеточие с помощью @selector
Просто приступим к разработке iPhone и Objective-C
.
Вчера я пытался добавить Observer для уведомления в моем представлении, и я продолжал получать эту ошибку:
unrecognized selector sent to instance
Я отследил это до того факта, что мне нужно было добавить конечную двоеточие в аргумент селектора:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nameOfMySelector:) name:@"BBLocationServicesAreDisabled" object:nil];
Сегодня я подумал, что умен, потому что когда я настраивал аргумент действия для кнопки, я вспомнил вчерашнюю ошибку и добавил двоеточие к аргументу действия. Аргумент действия принимает @selector
, точно так же, как аргумент селектора при настройке наблюдателя для NSNotification
, поэтому я решил, что NSNotification
правильно.
Тем не менее, с помощью следующего кода:
[self.callToActionButton addTarget:self action:@selector(nameOfMySelector:) forControlEvents:UIControlEventTouchUpInside];
Я получаю точно такую же ошибку:
unrecognized selector sent to instance
Что дает? Почему один @selector
требует @selector
двоеточия, а другой нет? Каковы правила, которым я должен следовать, когда это должно быть включено и когда это должно быть прекращено, и почему я не могу всегда делать одно или другое?
Спасибо!
Ответы
Ответ 1
Как упоминалось boltClock, характер, на который вы ссылаетесь, на самом деле является двоеточием. Разница между @selector(method)
и @selector(method:)
является сигнатурой метода. Второй вариант ожидает передачи параметра.
@selector(method)
ожидал бы метод: -(void)method
@selector(method:)
ожидал бы метод: -(void)method:(id)someParameter
Ответ 2
Кажется, у вас отсутствует одна концепция: двоеточие, в некотором роде, является частью имени метода. Например, метод
-(IBAction) doIt:(id)sender;
имеет имя doIt:
. Таким образом, двоеточие должно использоваться для ссылки на этот метод.
Но этот метод не имеет двоеточия в конце
-(IBAction) doItWithoutParameter;
То же самое касается методов, принимающих несколько аргументов, у них есть имена типа doItWithParam1:andParam2:
Ответ 3
Селектор представляет имя метода, а количество двоеточий в селекторе соответствует количеству аргументов в соответствующем методе:
-
mySelector
- нет двоеточия, нет аргументов, например. - (void)mySelector;
, [self mySelector];
-
mySelectorWithFoo:
- один двоеточие, один аргумент, например. - (void)mySelectorWithFoo:(Foo *)foo;
, [self mySelectorWithFoo:someFoo];
-
mySelectorWithFoo:withBar:
- два двоеточия, два аргумента, например. - (void)mySelectorWithFoo:(Foo *)foo bar:(Bar *)bar;
, [self mySelectorWithFoo:someFoo bar:someBar];
и т.д.
Также возможно иметь селектор без "именования параметров". Его не рекомендуется, так как он не сразу определяет, какие параметры:
-
mySelector::
- два двоеточия, два аргумента, например. - (void)mySelector:(Foo *)foo :(Bar *)bar;
, [self mySelector:someFoo :someBar];
-
mySelector:::
- три двоеточия, три аргумента, например. - (void)mySelector:(int)x :(int)y :(int)z;
, [self mySelector:2 :3 :5];
Ответ 4
Двоеточие указывает, что метод принимает параметр.
[someObject performSelector:@selector(doSomething:)]
означает, что doSomething ожидает параметр.
[someObject performSelector:@selector(doSomething)]
означает, что doSomething не нуждается в каких-либо параметрах.
Ответ 5
В вашем случае:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nameOfMySelector:) name:@"BBLocationServicesAreDisabled" object:nil];
- (void) nameOfMySelector: (NSNotification *) notification {
/* this method would require the semi-colon */
}
или в этом случае:
[self.callToActionButton addTarget:self action:@selector(nameOfMySelector:) forControlEvents:UIControlEventTouchUpInside];
- (void) nameOfMySelector: (id) sender {
/* this method would also require the semi-colon */
}
Ответ 6
Я думаю, что проблема - недостающий параметр.
Смотрите это сообщение: Objective-C: Вызов селекторов с несколькими аргументами (Отличные ответы!)