在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设计师的陈述原因;是否有人偶然知道Brad Cox或Tom Love?他们在这里吗?)或那句话如何编写方法名称,以便不需要该功能。主要的好处是可读性和可写性(这与可读性一样,只是...您知道),因为这意味着您可以编写与自然语言句子更加相似的方法名称。这样的人-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication
(马特·加拉格尔指出的“可可的爱”-(BOOL)application:(NSApplication*)theApplication shouldTerminateAfterLastWindowClosed
,因此将参数直接放在适当名词的旁边。
苹果的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;
}