Ich habe mein Protokoll definiert. Ich habe zwei meiner Protokollmethoden als optional erwähnt. Wie kann ich während der Laufzeit herausfinden, ob die bestimmte Methode optional ist oder nicht? Gibt es eine Möglichkeit, das herauszufinden?Wie erkennt man eine Protokollmethode während der Laufzeit?
Antwort
Dies sollte tun, was Sie wollen:
BOOL MethodInProtocolIsRequired(Protocol *protocol, SEL methodSelector)
{
struct objc_method_description methodDesc = protocol_getMethodDescription(protocol, methodSelector, YES, YES);
return methodDesc.name != NULL;
}
Bitte beachte, dass ich nicht auf die Ratsamkeit kommentieren dies mit in der Postleitzahl, besonders, weil Sie nicht erklärt haben, warum Sie dies tun möchten. Beachten Sie außerdem, dass diese Funktion NO zurückgibt, wenn ein Selektor für eine Methode angegeben wird, die das Protokoll nicht enthält. Das ist im Grunde vernünftig (schließlich, wenn ein Protokoll keine Methode enthält, ist es nicht erforderlich!), Aber Sie könnten die Funktion verfeinern, indem Sie prüfen, ob das Protokoll die Methode als optionale Methode enthält und etwas anderes zurückgibt alle drei Szenarien (erforderlich, optional, nicht im Protokoll).
EDIT: Einfaches Testprogramm hier: https://gist.github.com/4381753
Ich sollte das wirklich tun anstatt meiner überkomplizierten Vorgehensweise. +1. (Kann ich das in meine Antwort aufnehmen?) –
Natürlich, und ich sehe, du hast es schon getan :). –
Yep, und ich stellte sicher, Attribution hinzufügen :) Diesmal bin ich es, der RTFM haben sollte ... -.- –
(ich weiß nicht, die Antwort aus der Spitze von meinem Kopf. 1 Minute googeln half mir.)
Sie können dies tun, um die protocol_copyMethodDescriptionList()
-Funktion, den Teil der Objective-C-Laufzeit ist Bibliothek (libobjc). Das zweite Argument dieser Funktion ist ein boolesches Flag, das angibt, ob die im Protokoll zu kopierenden Methoden erforderlich sind. Wenn also eine Methode in der Liste enthalten ist, die von dieser Funktion zurückgegeben wird (die mit den entsprechenden Argumenten aufgerufen wird), ist sie eine erforderliche Methode.
SEL sctr = @selector(isThisMethod:requiredIn:theProtocol:);
struct objc_method_description *methods;
unsigned int nMethods;
methods = protocol_copyMethodDescriptionList(
objc_getProtocol("MyProtocolName"), // or @protocol(MyProtocolName) if you don't need this kind of dynamism
YES, // required?
YES, // instance method? (in general, protocols declare instance methods)
&nMethods
);
BOOL isRequired = NO;
int i;
SEL s;
const char *sctrStr = sel_getName(sctr);
for (i = 0; i < nMethods; i++) {
s = methods[i].name;
const char *sStr = sel_getName(s);
if (strcmp(sctrScr, sStr) == 0) {
isRequired = YES;
break;
}
}
free(methods);
if (isRequired) {
// required
} else {
// optional
}
Also, das ist möglich, aber es ist ein bisschen zuviel des Guten, und wie ich schon in meinem Kommentar zu Ihrer Frage erwähnt, sollten Sie nicht testen für ein Verfahren optional oder erforderlich ist, sollten Sie sich für einen Test Instanz reagiert auf einen bestimmten Selektor.
Edit: ja, anstatt das ganze Universum zu kopieren, hätte ich weiter in der Dokumentation gelesen. Wie Andrew Madsen darauf hingewiesen, kann dies auf ein paar Zeilen reduziert werden:
struct objc_method_description method;
method = protocol_getMethodDescription(
objc_getProtocol("MyProtocolName"), // or @protocol(MyProtocolName)
@selector(isThisSelector:required:)
YES, // required?
YES // instance method?
);
if (method.name != NULL) {
// required
} else {
// optional
}
Warum auf der Erde würde jemand seinen Upvote zu einem Downvote ändern? –
Wenn Sie nur GNU c booleans verwenden würden, könnten Sie schließlich sagen, dass Sie eine Objective-C-Frage ohne ObjC beantwortet haben! (Extrem technisch aber). – CodaFi
@CodaFi: Oder C99 'bool' /' _Bool'. –
- 1. Ziehen während der Laufzeit
- 2. Wie erkennt man den Schnittpunkt zweier Bilder während der Animation?
- 3. XSLT, wie erkennt man ein anderes Muster während der Transformation?
- 4. Wie erkennt man die Standard-GPU zur Laufzeit?
- 5. Go (reflect): Wie erkennt man alle Pakettypen zur Laufzeit?
- 6. Schleifen Variablen während der Laufzeit
- 7. Anwendungskonfiguration während der Laufzeit einrichten
- 8. TensorFlow: OOM während der Laufzeit
- 9. Wie Array-Werte während der Laufzeit
- 10. Wie Dialekt während der Laufzeit Ruhezustand erhalten
- 11. Wie erkennt JavaScript zur Laufzeit Instanztypen?
- 12. Wie man es6 Module erkennt
- 13. Mehrdeutiger Referenzfehler während der Kompilierung der Laufzeit
- 14. App-Einstellungen während der Laufzeit ändern
- 15. Ändern der Kafka-Aufbewahrungsdauer während der Laufzeit
- 16. Überprüfung, ob eine optionale Protokollmethode implementiert wurde
- 17. Partielle Anwendung der Protokollmethode ist nicht erlaubt
- 18. Warum verursacht eine fehlende Anmerkung während der Laufzeit keine ClassNotFoundException?
- 19. Java Keystore während der Laufzeit neu laden
- 20. Wie man eine sich wiederholende Dezimalzahl erkennt
- 21. Doppelte Ansichten auf Android während der Laufzeit
- 22. Wie erkennt man Anwendungsabstürze?
- 23. Interrupt-On-Change während der Laufzeit
- 24. Kann eine C++ - Klasseninstanziierung ihre Größe während der Laufzeit ändern
- 25. Neudefinieren eines aufrufbaren Objekts während der Laufzeit
- 26. Wie erkennt man eine Firewall in Windows?
- 27. Javascript - Wie erkennt man eine Elementbreitenänderung?
- 28. UITableView - Wie erkennt man eine Abwahl?
- 29. Wie erkennt man eine Dateiänderungen mit TFS?
- 30. Wie man eine Spirale erkennt und zählt
Warum diese Informationen würden zur Laufzeit benötigt werden? (Nur neugierig.) –
@NikolaiRuhe Ja, +1 für diesen Kommentar. Im Allgemeinen sollten wir keine Annahmen machen, sondern Testfunktionen. I. e., Sollte man anstelle von der Annahme, dass eine erforderliche Methode implementiert ist, nach "answerToSelector:" testen. –
Oder Sie können ein Wörterbuch selbst mit dem Namen der Methoden als Schlüssel und seinem Wert als JA/NEIN erstellen, um zu überprüfen, ob es erforderlich ist oder nicht. –