Selektoren in Objective-C?

122

Erstens bin ich mir nicht sicher, ob ich wirklich verstehe, was ein Selektor ist. Nach meinem Verständnis ist dies der Name einer Methode, und Sie können ihn einer Klasse vom Typ 'SEL' zuweisen und dann Methoden wie replyToSelector ausführen, um festzustellen, ob der Empfänger diese Methode implementiert. Kann jemand eine bessere Erklärung anbieten?

Zweitens habe ich bis zu diesem Punkt den folgenden Code:

NSString *thing = @"Hello, this is Craig";

SEL sel = @selector(lowercaseString:);
NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO");
NSLog (@"Responds to lowercaseString: %@", lower);
if ([thing respondsToSelector:sel]) //(lower == @"YES")
    NSLog(@"lowercaseString is: %@", [thing lowercaseString]);

Obwohl thinges sich eindeutig um eine Art NSString handelt und auf KleinbuchstabenString reagieren sollte, kann ich die Bedingung 'respondsToSelector' nicht erhalten, um "YES" zurückzugeben ...

Craig
quelle
Sie möchten die Selektorbeschreibung auf der Apple-Entwicklerseite lesen: Selektoren .
Lothar
14
Stanford Kurs CS193P Aufgabe 1B? Ich habe hier genau die gleiche Frage! :)
Corstian Boerman

Antworten:

181

Sie müssen sehr vorsichtig mit den Methodennamen sein. In diesem Fall lautet der Methodenname nur " lowercaseString", nicht " lowercaseString:" (beachten Sie das Fehlen des Doppelpunkts). Aus diesem Grund werden Sie NOzurückgegeben, da NSStringObjekte auf die lowercaseStringNachricht antworten, nicht jedoch auf die lowercaseString:Nachricht.

Woher wissen Sie, wann Sie einen Doppelpunkt hinzufügen müssen? Sie fügen dem Nachrichtennamen einen Doppelpunkt hinzu, wenn Sie beim Aufrufen einen Doppelpunkt hinzufügen würden. Dies geschieht, wenn ein Argument erforderlich ist. Wenn keine Argumente verwendet werden (wie dies bei der Fall ist lowercaseString), gibt es keinen Doppelpunkt. Wenn mehr als ein Argument erforderlich ist, müssen Sie die zusätzlichen Argumentnamen zusammen mit ihren Doppelpunkten wie in hinzufügen compare:options:range:locale:.

Sie können sich auch die Dokumentation ansehen und feststellen, ob ein nachfolgender Doppelpunkt vorhanden ist oder nicht.

Adam Rosenfield
quelle
12

Selektoren sind eine effiziente Möglichkeit, Methoden direkt im kompilierten Code zu referenzieren - der Compiler weist den Wert tatsächlich einem SEL zu.

Andere haben bereits den zweiten Teil Ihres q behandelt. Das ':' am Ende entspricht einer anderen Signatur als das, wonach Sie suchen (in diesem Fall existiert diese Signatur nicht).

dstnbrkr
quelle
10

Das ist , weil Sie wollen @selector(lowercaseString), nicht @selector(lowercaseString:). Es gibt einen subtilen Unterschied: Der zweite impliziert einen Parameter (beachten Sie den Doppelpunkt am Ende), nimmt jedoch - [NSString lowercaseString]keinen Parameter an.

Mipadi
quelle
5

In diesem Fall ist der Name des Selektors falsch. Der Doppelpunkt hier ist Teil der Methodensignatur. Dies bedeutet, dass die Methode ein Argument akzeptiert. Ich glaube, dass du willst

SEL sel = @selector(lowercaseString);
mkb
quelle
3

Die Methode von NSString ist lowercaseString(0 Argumente), nicht lowercaseString:(1 Argument).

Nicholas Riley
quelle
1

Stellen Sie sich den Doppelpunkt nicht als Teil des Funktionsnamens vor, sondern als Trennzeichen. Wenn Sie nichts zu trennen haben (kein Wert für die Funktion), brauchen Sie ihn nicht.

Ich bin mir nicht sicher warum, aber all dieses OO-Zeug scheint Apple-Entwicklern fremd zu sein. Ich würde dringend empfehlen, sich Visual Studio Express zu schnappen und damit herumzuspielen. Nicht weil eines besser ist als das andere, es ist nur eine gute Möglichkeit, die Designprobleme und Denkweisen zu betrachten.

Mögen

introspection = reflection
+ before functions/properties = static
- = instance level

Es ist immer gut, ein Problem auf unterschiedliche Weise zu betrachten, und die Programmierung ist das ultimative Rätsel.


quelle
0

Nach meinem Verständnis der Apple-Dokumentation repräsentiert ein Selektor den Namen der Methode, die Sie aufrufen möchten. Das Schöne an Selektoren ist, dass Sie sie in Fällen verwenden können, in denen die genaue aufzurufende Methode variiert. Als einfaches Beispiel können Sie Folgendes tun:

SEL selec;
if (a == b) {
selec = @selector(method1)
}
else
{
selec = @selector(method2)
};
[self performSelector:selec];
moonman239
quelle
0

Gemäß Apple-Dokumenten: https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html

Ein Selektor ist der Name, mit dem eine für ein Objekt auszuführende Methode ausgewählt wird, oder die eindeutige Kennung, die den Namen beim Kompilieren des Quellcodes ersetzt. Ein Selektor selbst macht nichts. Es identifiziert einfach eine Methode. Das einzige, was den Namen der Selektormethode von einer einfachen Zeichenfolge unterscheidet, ist, dass der Compiler sicherstellt, dass die Selektoren eindeutig sind. Was einen Selektor nützlich macht, ist, dass er (in Verbindung mit der Laufzeit) wie ein dynamischer Funktionszeiger wirkt, der für einen bestimmten Namen automatisch auf die Implementierung einer Methode verweist, die für die jeweilige Klasse geeignet ist. Angenommen, Sie hatten einen Selektor für den Methodenlauf und die Klassen Dog, Athlete und ComputerSimulation (von denen jede einen Methodenlauf implementiert hat).

Beispiel: (lldb) Haltepunkt - Set Selector viewDidLoad

Dadurch wird ein Haltepunkt für alle viewDidLoad-Implementierungen in Ihrer App festgelegt. Der Selektor ist also eine Art globaler Bezeichner für eine Methode.

Adrian
quelle