In Objective-C können Sie keine Methodennamen deklarieren, bei denen die letzte Komponente kein Argument akzeptiert. Zum Beispiel ist Folgendes illegal.
-(void)take:(id)theMoney andRun;
-(void)take:(id)yourMedicine andDontComplain;
Warum wurde Objective-C so konzipiert? War es nur ein Artefakt von Smalltalk, das niemand für nötig hielt, um es loszuwerden?
Diese Einschränkung ist in Smalltalk sinnvoll, da Smalltalk keine Begrenzer für den Nachrichtenaufruf hat, sodass die letzte Komponente als unäre Nachricht zum letzten Argument interpretiert wird. Zum Beispiel BillyAndBobby take:'$100' andRun
würde analysiert werden als BillyAndBobby take:('$100' andRun)
. Dies spielt in Objective-C keine Rolle, wo eckige Klammern erforderlich sind.
Die Unterstützung parameterloser Auswahlkomponenten würde uns nicht auf die übliche Weise, wie eine Sprache gemessen wird, viel bringen, wie der Methodenname, den ein Programmierer auswählt (z. B. runWith:
anstatttake:andRun
) beeinflusst weder die funktionale Semantik eines Programms noch die Ausdruckskraft der Sprache. In der Tat ist ein Programm mit parameterlosen Komponenten Alpha-Äquivalent zu einem ohne. Ich bin daher nicht an Antworten interessiert, die besagen, dass eine solche Funktion nicht erforderlich ist (es sei denn, dies waren die angegebenen Gründe der Objective-C-Designer; kennt jemand Brad Cox oder Tom Love? Sind sie hier?) Oder diese sagen wie man Methodennamen schreibt, damit die Funktion nicht benötigt wird. Der Hauptvorteil ist die Lesbarkeit und Schreibbarkeit (was nur Lesbarkeit entspricht ... Sie wissen), da dies bedeuten würde, dass Sie Methodennamen schreiben könnten, die Sätzen in natürlicher Sprache noch ähnlicher sind. Ähnliches -(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication
(worauf Matt Gallagher in "Cocoa With Love" hinweist-(BOOL)application:(NSApplication*)theApplication shouldTerminateAfterLastWindowClosed
Dadurch wird der Parameter unmittelbar neben dem entsprechenden Substantiv platziert.
Die Objective-C-Laufzeit von Apple (zum Beispiel) kann diese Art von Selektoren perfekt verarbeiten. Warum also nicht den Compiler? Warum unterstützen Sie sie nicht auch in Methodennamen?
#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;
}
takeAndRunWith:(id)theMoney
undtakeAndDon'tComplainAbout:(id)yourMedicine
. Grammatisch umständlich, um sicher zu sein.- (void) :(id)theMoney;
oder- (void) :(id)obj1 :(id)obj2;
. Selektoren, die nur aus Doppelpunkten bestehen, sind also in Ordnung. ;-)Antworten:
Das ist Brad Cox. Meine ursprüngliche Antwort hat die Frage falsch verstanden. Ich nahm an, dass wirklich Fast eine fest codierte Erweiterung war, um schnelleres Messaging auszulösen, keine Art syntaktischen Zuckers. Die eigentliche Antwort ist, dass Smalltalk es nicht unterstützt hat, vielleicht weil sein Parser die (angenommene) Mehrdeutigkeit nicht bewältigen konnte. Obwohl die eckigen Klammern von OC jede Mehrdeutigkeit beseitigen würden, dachte ich einfach nicht daran, von der Keyword-Struktur von Smalltalk abzuweichen.
quelle
21 Jahre Programmieren von Objective-C und diese Frage ist mir nie in den Sinn gekommen. In Anbetracht des Sprachdesigns ist der Compiler richtig und die Laufzeitfunktionen sind falsch ().
Der Begriff der verschachtelten Argumente mit Methodennamen hat immer bedeutet, dass bei mindestens einem Argument das letzte Argument immer der letzte Teil der Methodenaufrufsyntax ist.
Ohne viel darüber nachzudenken, würde ich wetten, dass es einige syntaktische Bugaboos gibt, bei denen das aktuelle Muster nicht durchgesetzt wird. Zumindest würde es den Compiler schwieriger machen, darin zu schreiben, dass jede Syntax, bei der optionale Elemente mit Ausdrücken verschachtelt sind, immer schwieriger zu analysieren ist. Möglicherweise gibt es sogar einen Randfall, der dies verhindert. Obj-C ++ würde es sicherlich schwieriger machen, aber das wurde erst Jahre, nachdem die Basissyntax bereits in Stein gemeißelt war, in die Sprache integriert.
Was den Grund angeht, warum Objective-C so entworfen wurde, würde ich vermuten, dass die Antwort der ursprünglichen Designer der Sprache einfach nicht in Betracht gezogen hat, die verschachtelte Syntax über dieses letzte Argument hinausgehen zu lassen.
Das ist eine gute Vermutung. Ich werde einen von ihnen fragen und meine Antwort aktualisieren, wenn ich mehr herausfinde.
Ich habe Brad Cox danach gefragt und er hat sehr großzügig im Detail geantwortet (Danke, Brad !!):
Lesen Sie Brads Antwort!
quelle
-myObjectWithDelegate: (id) foo wantsYouToDoSomethingWith: (id) bar
. Dies führt zu einer störenden Inkonsistenz der Methodennamen, wenn Sie eine Methode im Protokoll haben, die keine anderen Parameter benötigt. Ein Beispiel finden Sie unter NSTableViewDataSource. Eine Methode folgt nicht dem schönen, ordentlichen Muster aller anderen.Nur zu Ihrer Information, die Laufzeit kümmert sich nicht wirklich um die Selektoren, jede C-Zeichenfolge ist gültig, Sie können auch einen Selektor wie diesen erstellen: "== + === + ---__-- ¨¨¨¨ ¨ ^ :::::: "Ohne Argument wird die Laufzeit dies akzeptieren, der Compiler kann es einfach nicht oder es ist unmöglich zu analysieren. Es gibt absolut keine Überprüfung der Gesundheit, wenn es um Selektoren geht.
quelle
Ich gehe davon aus, dass sie in Objective-C nicht unterstützt werden, da sie auch in Smalltalk nicht verfügbar waren. Aber das hat einen anderen Grund als Sie denken: Sie werden nicht benötigt. Was benötigt wird, ist die Unterstützung von Methoden mit 0, 1, 2, 3, ... Argumenten. Für jede Anzahl von Argumenten gibt es bereits eine funktionierende Syntax, um sie aufzurufen. Das Hinzufügen einer anderen Syntax würde nur zu unnötiger Verwirrung führen.
Wenn Sie parametrlose Selektoren mit mehreren Wörtern wollten, warum sollten Sie dann mit einem einzigen zusätzlichen Wort aufhören? Das könnte man dann fragen
wird auch unterstützt (dh ein Selektor ist eine Folge von Wörtern, einige mit Doppelpunkt und einem Parameter, andere nicht). Dies wäre zwar möglich gewesen, aber ich gehe davon aus, dass es niemand für lohnenswert hielt.
quelle
and
undor
wäre ein besonderer Stolperstein). Dies würde weitaus weniger passieren, wenn nur die letzte Komponente eines Methodennamens keinen Parameter haben dürfe, da sie in der Regel aus mehreren Wörtern bestehen würde.