Objective-C подписи методов. Они непоследовательны?

Я новичок в Objective-C, но, пожалуйста, помогите мне здесь.

То, что я вижу, это то, что сигнатуры метода в Objective-C, которые принимают несколько параметров, кажутся непоследовательными.

Пример:

- (void) sendEmail: (NSString *) toStr
         subject:(NSString *) subjectStr
         body:(NSString *) bodyStr;

ОК, поэтому у нас есть 3 "параметра" (по крайней мере, то, что я использую для их вызова), но у 2 из них есть "внешние" имена (субъект, тело), ​​но первый нет! Разве что-то не так с этим связано с точки зрения согласованности/стиля?

Когда мы вызываем этот метод, мы делаем это так:

[emailObj sendEmail:@"[email protected]" subject:@"testSub" body:@"this is a test"]

(Надеюсь, я сделал это правильно, помню, что я новичок в этом.)

Значит, субъект и тело четко обозначены в вызове, но не "на" адрес? Кажется, мне действительно не хватало. Почему этот первый параметр получает специальное лечение?

Ответы

Ответ 1

Я думаю, вы думали, что в объявлении метода

-(void) A:(NSObject*)a B:(NSObject*)b C:(NSObject*)c

A - это имя метода, B и C - это имена параметров.

В Objective-C совокупность A:B:C: - это имя метода (более технически называемое селектором) и используется как единица при вызове метода по имени. Например,

 if([obj respondsToSelector:@selector(A:B:C:)]){
     ...
 }

проверяет, отвечает ли obj на A:B:C:. Но [obj respondsToSelector:@selector(A:)] будет NO в этом случае.

Итак, вы должны действительно думать о совокупности A:B:C: как имя метода, а A - имя первого параметра.

Обратите внимание, что вы также не можете вызвать A:B:C: как A:C:B:.

Ответ 2

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

Ответ 3

Я бы сказал, что если вы запутались в том, что делает метод, то он, вероятно, не назван так хорошо, как мог бы быть.

Учитывая вышеописанный селектор, я бы ожидал, что 3 параметра будут своего рода объектом электронной почты, субъектом и телом. Поскольку, однако, первый параметр не является объектом "Электронная почта", а скорее получателем сообщения электронной почты, я бы, вероятно, переименовал этот метод:

- (void) sendEmailToRecipient:(NSString *)recipient subject:(NSString *)subject body:(NSString *)body;