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

标签 objective-c selector language-design

在 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 (Matt Gallagher 指出 on "Cocoa With Love" 在您删除形式参数时有点令人困惑)可以命名为 -(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;
}

最佳答案

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

关于objective-c - 为什么 Objective-C 方法名称的最后一部分必须带一个参数(当有多个部分时)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4479967/

相关文章:

objective-c - JXA:从CoreServices访问CFString常量

iphone - 让 UILabel 产生省略号而不是缩小字体

objective-c - NSTimer 在触发时导致 "unrecognized selector"崩溃

ios - 在 superView 上执行选择器

ios - 当键盘按下并且 x 被点击时,在 UISearchBar 上执行操作

c++ - vector 复制值

iphone - 当我使用 2 个 TableView 时,如何将数据(托管对象)从一个 TableView 移动到另一个 TableView ?

ios - 如何将一个 IBOutlet 连接到容器 View Controller 中的 TableView Controller

reflection - 基于镜子的反射和传统反射有什么区别?

c# - 我不明白为什么我们需要 'new' 关键字