2010-04-20 3 views
10

Может ли кто-нибудь просветить меня относительно различий между этими двумя утверждениями ниже.Использование [self method] или @selector (method)?

[self playButtonSound]; 

И:

[self performSelector:@selector(playButtonSound)]; 

Я просто спрашиваю, как у меня был какой-то старый код, который использовал @selector, теперь с немного больше знаний я не могу понять, почему я не использовал [self playButtonSound] вместо этого, они оба, похоже, делают то же самое, что и здесь.

Гэри

+0

Спасибо, я понимаю, очень ценю. – fuzzygoat

+1

Ван: почему вы удалили, это полезно, не так ли? Они определенно сделают то же самое. Небольшая разница заключается в том, что в первом примере будет отправлено одно сообщение playButtonSound; второй будет отправлять два сообщения, сначала выполнитьSelector :, который затем отправит playButtonSound. Я всегда буду использовать первый вариант, если у вас нет выбора, если только для удобства чтения. – fuzzygoat

ответ

10

И в то же самое, но [self playButtonSound];, безусловно, нормальный способ вызвать метод в Objective-C. Однако использование performSelector: позволяет вызывать метод, который определяется только во время выполнения.

Из NSObject Protocol Reference:

performSelector: метод эквивалентен отправкой aSelector сообщения непосредственно к приемнику. Для Например, все три из следующих сообщений сделать то же самое:

id myClone = [anObject copy]; 
id myClone = [anObject performSelector:@selector(copy)]; 
id myClone = [anObject performSelector:sel_getUid("copy")]; 

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

SEL myMethod = findTheAppropriateSelectorForTheCurrentSituation(); 
[anObject performSelector:myMethod]; 
+1

Наткнулся на этот ответ и научился! Благодаря! – Groot

6
[self playButtonSound]; 

Здесь компилятор будет проверять, если ваш объект реагирует на -playButtonSound сообщений и даст вам предупреждение, если он не делает.

[self performSelector:@selector(playButtonSound)]; 

Вызов -playButtonSound таким образом, вы не получите предупреждение компилятора. Однако вы можете динамически проверять, реагируют ли объекты на определенный селектор, поэтому вы можете безопасно попытаться вызвать произвольный селектор объекта без указания его типа и не получать предупреждения о компиляторе (что может быть полезно, например, для вызова дополнительных методов в делетете объектов) :

if ([self respondsToSelector:@selector(playButtonSound)]) 
    [self performSelector:@selector(playButtonSound)]; 
+0

Отсутствует скобка в строке 'if ([self responsesToSelector: @selector (playButtonSound)]' -it должен быть 'if ([self responsesToSelector: @selector (playButtonSound)]). –

+2

Собственно, вы можете иметь компилятор бросить предупреждение в необъявленных селекторах, добавив -Wundeclared-selector в поле Other Warning Flags в ваших настройках сборки. Я считаю, что это очень полезно. –

Смежные вопросы