为什么 Objective-C 方法名称的最后一部分必须带有参数(当有多个部分时)?

2024-05-17

在 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) 不影响程序的功能语义,也不影响语言的表达能力。事实上,带有无参数组件的程序与没有无参数组件的程序在 alpha 版本上是等价的。因此,我对那些声称不需要这样的功能的答案不感兴趣(除非这是 Objective-C 设计师所陈述的原因;有人碰巧认识 Brad Cox 或 Tom Love?他们在这里吗?)或者说如何编写方法名称以便不需要该功能。主要好处是可读性和可写性(这就像可读性,只是……你知道),因为这意味着你可以编写更类似于自然语言句子的方法名称。喜欢的-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication http://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSApplicationDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/NSApplicationDelegate/applicationShouldTerminateAfterLastWindowClosed:(马特·加拉格尔指出关于“可可与爱” http://cocoawithlove.com/2009/06/method-names-in-objective-c.html当你删除形式参数时有点混乱)可以命名-(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;
}

这是布拉德·考克斯。我原来的回答误解了这个问题。我认为 trueFast 是一个硬编码扩展,用于触发更快的消息传递,而不是一种语法糖。真正的答案是 Smalltalk 不支持它,也许是因为它的解析器无法处理(假设的)歧义。尽管 OC 的方括号可以消除任何歧义,但我只是没有想到要背离 Smalltalk 的关键字结构。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Objective-C 方法名称的最后一部分必须带有参数(当有多个部分时)? 的相关文章

随机推荐