1. ホーム
  2. objective-c

[解決済み] Objective-Cのメソッド名の最後の部分はなぜ引数を取らなければならないのですか(複数の部分がある場合)?

2023-04-08 04:20:41

質問

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 (マット・ギャラガーが指摘する を、"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;
}

どのように解決するのですか?

ブラッド・コックスです。私の元の回答は質問を誤解していました。私は reallyFast が構文上の砂糖の一種ではなく、より高速なメッセージングをトリガーするハードコードされた拡張機能であると仮定していました。本当の答えは、Smalltalk がそれをサポートしなかったということです。おそらく、そのパーサーが(想定される)曖昧さを処理できなかったからでしょう。OC の角括弧は曖昧さを取り除きますが、私は単に Smalltalk のキーワード構造から離れることを考えませんでした。