it-swarm.com.de

Selektoren in Ziel C

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

Zweitens habe ich zu diesem Zeitpunkt 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 thing eindeutig eine Art NSString ist und auf KleinbuchstabenString reagieren sollte, kann ich nicht die Bedingung 'responsondsToSelector' erhalten, um "YES" zurückzugeben.

119
Craig

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). Deshalb erhalten Sie NO zurückgegeben, da NSString-Objekte auf die lowercaseString-Nachricht, nicht jedoch auf die lowercaseString:-Nachricht reagieren.

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. Dies geschieht, wenn ein Argument erforderlich ist. Wenn es null Argumente braucht (wie bei lowercaseString), gibt es keinen Doppelpunkt. Wenn mehr als ein Argument erforderlich ist, müssen Sie die zusätzlichen Argumentnamen zusammen mit ihren Doppelpunkten hinzufügen, wie in compare:options:range:locale:.

Sie können sich auch die documentation ansehen und feststellen, ob ein Doppelpunkt nachgestellt ist oder nicht.

174
Adam Rosenfield

Das liegt daran, dass Sie @selector(lowercaseString) und nicht @selector(lowercaseString:) wünschen. Es gibt einen subtilen Unterschied: Der zweite Parameter impliziert einen Parameter (beachten Sie den Doppelpunkt am Ende), aber - [NSString lowercaseString] nimmt keinen Parameter an.

9
mipadi

Selectors sind ein effizienter Weg, um Methoden direkt in kompiliertem Code zu referenzieren - der Compiler ist es, der einem SEL tatsächlich den Wert zuweist.

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

8
dstnbrkr

In diesem Fall ist der Name des Selektors falsch. Der Doppelpunkt hier ist Teil der Methodensignatur; es bedeutet, dass die Methode ein Argument benötigt. Ich glaube, dass du willst

SEL sel = @selector(lowercaseString);
5
mkb

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

3
Nicholas Riley

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

Ich bin nicht sicher warum, aber all das OO Zeug scheint Apple-Entwicklern fremd zu sein. Ich würde dringend empfehlen, Visual Studio Express zu nutzen und auch damit herumzuspielen. Nicht weil eines besser ist als das andere, es ist nur ein guter Weg, um Designfragen und Denkweisen zu betrachten.

Mögen

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

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

1
Roger Roger

Laut Apple-Dokumenten: https://developer.Apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html

Ein Selektor ist der Name, der zur Auswahl einer Methode für ein Objekt verwendet wird, oder der eindeutige Bezeichner, der den Namen ersetzt, wenn der Quellcode kompiliert wird. Ein Selector alleine macht nichts. Es identifiziert einfach eine Methode. Der Name der Selektormethode unterscheidet sich von einer einfachen Zeichenfolge nur dadurch, dass der Compiler sicherstellt, dass 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 gegebenen Namen automatisch auf die Implementierung einer Methode verweist, die für die Klasse geeignet ist, mit der er verwendet wird. Angenommen, Sie hatten einen Selektor für den Methodenlauf und die Klassen Dog, Athlet und ComputerSimulation (die jeweils einen Methodenlauf implementierten). Der Selektor kann mit einer Instanz jeder Klasse verwendet werden, um die Run-Methode aufzurufen - auch wenn die Implementierung für jede Klasse unterschiedlich sein kann.

Beispiel: (Lldb) Haltepunkt --set Selector viewDidLoad

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

0
Sergheev

Nach meinem Verständnis der Apple-Dokumentation steht ein Selektor für den Namen der Methode, die Sie aufrufen möchten. Das Schöne an Selektoren ist, dass sie in Fällen verwendet werden können, in denen die genaue Methode unterschiedlich ist. Als einfaches Beispiel können Sie Folgendes tun:

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