В Objective-C вы не можете объявлять имена методов, где последний компонент не принимает аргумента. Например, следующее недопустимо.
-(void)take:(id)theMoney andRun;
-(void)take:(id)yourMedicine andDontComplain;
Почему Objective-C был разработан таким образом? Был ли это просто артефакт Smalltalk, от которого никто не видел необходимости избавляться?
Это ограничение имеет смысл в Smalltalk, поскольку Smalltalk не имеет разделителей вокруг вызова сообщения, поэтому последний компонент будет интерпретироваться как унарное сообщение для последнего аргумента. Например, BillyAndBobby take:'$100' andRun
будет проанализировано как BillyAndBobby take:('$100' andRun)
. Это не имеет значения в Objective-C, где требуются квадратные скобки.
Поддержка компонентов селектора без параметров не принесет нам большой пользы во всех обычных способах измерения языка, так как имя метода, которое выбирает программист (например, runWith:
вместо take:andRun
), не влияет на функциональную семантику программа, ни выразительность языка. Действительно, программа с компонентами без параметров является альфа-эквивалентом программы без. Таким образом, меня не интересуют ответы, в которых говорится, что такая функция не нужна (если только это не было заявленными причинами дизайнеров Objective-C; кто-нибудь случайно не узнал Брэда Кокса или Тома Лава? Они здесь?) Или что-то вроде этого? как писать имена методов, чтобы эта функция не была нужна. Основным преимуществом является удобочитаемость и удобочитаемость (которые похожи на удобочитаемость, только ... вы знаете), поскольку это может означать, что вы могли бы писать имена методов, которые еще больше напоминают предложения на естественном языке. Подобные -(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication
(которые Мэтт Галлахер указывает на на «Какао с любовью» немного сбивает с толку, когда вы отбрасываете формальный параметр) могут быть названы -(BOOL)application:(NSApplication*)theApplication shouldTerminateAfterLastWindowClosed
, таким образом поместив параметр непосредственно рядом с соответствующим существительным.
Среда выполнения Apple Objective-C (например) вполне способна обрабатывать селекторы такого типа, так почему бы не компилятор? Почему бы не поддерживать их в именах методов?
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface Potrzebie : NSObject
-(void)take:(id)thing;
@end
@implementation Potrzebie
+(void)initialize {
SEL take_andRun = NSSelectorFromString(@"take:andRun");
IMP take_ = class_getMethodImplementation(self, @selector(take:));
if (take_) {
if (NO == class_addMethod(self, take_andRun, take_, "@@:@")) {
NSLog(@"Couldn't add selector '%@' to class %s.",
NSStringFromSelector(take_andRun),
class_getName(self));
}
} else {
NSLog(@"Couldn't find method 'take:'.");
}
}
-(void)take:(id)thing {
NSLog(@"-take: (actually %@) %@",NSStringFromSelector(_cmd), thing);
}
@end
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Potrzebie *axolotl=[[Potrzebie alloc] init];
[axolotl take:@"paradichloroaminobenzaldehyde"];
[axolotl performSelector:NSSelectorFromString(@"take:andRun")
withObject:@"$100"];
[axolotl release];
[pool release];
return 0;
}