为什么Objective-C方法名称的最后一部分必须带一个参数(当有多个部分时)? [英] Why must the last part of an Objective-C method name take an argument (when there is more than one part)?

查看:107
本文介绍了为什么Objective-C方法名称的最后一部分必须带一个参数(当有多个部分时)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Objective-C中,您不能在最后一个组件不带参数的地方声明方法名称.例如,以下内容是非法的.

In Objective-C, you can't declare method names where the last component doesn't take an argument. For example, the following is illegal.

-(void)take:(id)theMoney andRun;
-(void)take:(id)yourMedicine andDontComplain;

为什么用Objective-C设计这种方式?只是Smalltalk的人工制品,没有人看到有必要摆脱它吗?

Why was Objective-C designed this way? Was it just an artifact of Smalltalk that no one saw a need to be rid of?

此限制在Smalltalk中是有意义的,因为Smalltalk在消息调用周围没有定界符,因此最终组件将被解释为最后一个参数的一元消息.例如,BillyAndBobby take:'$100' andRun将被解析为BillyAndBobby take:('$100' andRun).在Objective-C中,这不需要括号.

This limitation makes sense in Smalltalk, since Smalltalk doesn't have delimiters around message invocation, so the final component would be interpreted as a unary message to the last argument. For example, BillyAndBobby take:'$100' andRun would be parsed as BillyAndBobby take:('$100' andRun). This doesn't matter in Objective-C where square brackets are required.

支持无参数选择器组件不会以一种通常的语言度量方式为我们带来很多好处,因为程序员选择的方法名称(例如runWith:而不是take:andRun)不会影响a的功能语义.程序,也不是语言的表现力.确实,具有无参数组件的程序与没有该组件的程序等效.因此,我对不需要此功能的答案不感兴趣(除非这是Objective-C设计师的陈述原因;是否有人偶然知道Brad Cox或Tom Love?他们在这里吗?)或那句话如何编写方法名称,以便不需要该功能.主要的好处是可读性和可写性(就像可读性一样,只是...您知道),因为这意味着您可以编写与自然语言句子更加相似的方法名称. -(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication (Matt Gallagher指出了 有点混乱,因此可以将其命名为-(BOOL)application:(NSApplication*)theApplication shouldTerminateAfterLastWindowClosed,从而将该参数直接放置在相应名词的旁边.

Supporting parameterless selector components wouldn't gain us much in all the usual ways a language is measured, as the method name a programmer picks (e.g. runWith: rather than take:andRun) doesn't affect the functional semantics of a program, nor the expressiveness of the language. Indeed, a program with parameterless components is alpha equivalent to one without. I'm thus not interested in answers that state such a feature isn't necessary (unless that was the stated reasons of the Objective-C designers; does anyone happen to know Brad Cox or Tom Love? Are they here?) or that say how to write method names so the feature isn't needed. The primary benefit is readability and writability (which is like readability, only... you know), as it would mean you could write method names that even more closely resemble natural language sentences. The likes of -(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication (which Matt Gallagher points out on "Cocoa With Love" is a little bit confusing when you drop the formal parameter) could be named -(BOOL)application:(NSApplication*)theApplication shouldTerminateAfterLastWindowClosed, thus placing the parameter immediately next to the appropriate noun.

例如,Apple的Objective-C运行时完全能够处理这类选择器,那么为什么不编译器呢?为什么不同时在方法名称中支持它们呢?

Apple's Objective-C runtime (for example) is perfectly capable of handling these kind of selectors, so why not the compiler? Why not support them in method names as well?

#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;
}

推荐答案

这是Brad Cox.我原来的答案误解了这个问题.我以为trueFast是一个硬编码的扩展,可以触发更快的消息传递,而不是一种语法糖.真正的答案是Smalltalk不支持它,可能是因为它的解析器无法处理(假定的)歧义.尽管OC的方括号可以消除任何歧义,但我只是没有想到脱离Smalltalk的关键字结构.

This is Brad Cox. My original answer misunderstood the question. I assumed reallyFast was a hardcoded extension to trigger faster messaging, not a kind of syntactic sugar. The real answer is that Smalltalk didn't support it, perhaps because its parser couldn't deal with the (assumed) ambiguity. Although OC's square brackets would remove any ambiguity, I simply didn't think of departing from Smalltalk's keyword structure.

这篇关于为什么Objective-C方法名称的最后一部分必须带一个参数(当有多个部分时)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆