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
、したがって、パラメータを適切な名詞のすぐ隣に配置します。
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;
}