Ich habe verwendet, um die Methoden von @optional
delegate zu versenden:
Es funktioniert gut, aber wenn es viele Methoden von Delegaten gibt, sieht es so aus, als ob du respondToSelector:
code ... duplizierst.
Irgendwann habe ich respondsToSelector:
auf separate Methode gesetzt:
Als Ergebnis habe ich nur einen respondToSelector: check, aber es sieht immer noch nicht wie gut aus.
%Vor% Was denkst du? Ist es sinnvoll, einige Helfer oder eine Kategorie zu verwenden, um alle @optional
delegate-Methoden zu senden oder etwas, das nicht verbessert werden sollte?
Die Leistung hängt davon ab, wie Sie den Delegaten verwenden, ob er sich direkt auf die Benutzeroberfläche auswirkt (in diesem Fall möchten Sie schnellere Antwortzeiten haben), usw.
Eine gute Geschwindigkeitsoptimierung besteht darin, alle vom Delegaten implementierten Methoden in einer Datenstruktur zu registrieren, wenn Sie den Delegierten zum ersten Mal setzen. Sie könnten tun:
%Vor%Dann können Sie einfach
tun %Vor%Sehen Sie sich diese großartige Antwort für eine ausführlichere Erklärung an.
Sie können dafür ein Trampolin benutzen. Ein Trampolin ist ein Objekt, das Nachrichten an ein anderes Objekt weiterleitet. Hier ist eine einfache DelegateTrampoline.
%Vor% %Vor%So würden Sie es verwenden:
%Vor%Einige Anmerkungen:
NSInvocation
-Objekt erstellt werden, das hundertmal langsamer als ein einfacher Methodenaufruf sein kann. Abgesehen davon, dass Sie Ihre Delegiertenmethode in einer engen Schleife aufrufen, ist das wahrscheinlich kein Problem. delegateTrampoline
vom Typ id
deklarieren. Dies ermöglicht Ihnen, beliebige Selektoren an sie zu übergeben. Es bedeutet aber auch, dass der Compiler nicht erkennen kann, ob Sie einen Selektor an delegateTrampoline
übergeben, der nicht im Protokoll enthalten ist. Sie werden zur Laufzeit abstürzen, wenn Sie dies tun. Der Compiler kann erkennen, ob Sie einen völlig unbekannten Selektor übergeben, sodass er einfache Tippfehler erkennt. Ganz oben auf der Antwort von @micantox würde ich hinzufügen, dass Sie anstelle von struct
NS_OPTIONS
verwenden könnten. um ein bitmask
zu definieren.
Sie könnten dann eine Eigenschaft erstellen, die bitmask
enthalten kann:
@property (nonatomic, assign) MyDelegateOptions delegateOptions;
und überprüfe, ob delegate respondsToSelector:
in deinem Setter wie
Dann können Sie einfach die zugewiesenen Bitmuster überprüfen, indem Sie bitwise AND
Wie Sie sehen können, wird die Verwendung von bitwise AND
true
zurückgeben, wenn das Bit für MyDelegateOptionDidFinishedWithTaskOne
auf 1 gesetzt ist, auch wenn andere Bits ebenfalls gesetzt sind.
Wenn Sie also davon ausgehen, dass delegate
in Ihrem Setter überprüft wurde, basiert Ihr delegateOptions
Bitmuster von 00000111 und Ihr MyDelegateOptionDidFinishedWithTaskOne
repräsentiert das Bitmuster von 00000001 dann einfach mit bitwise AND
00000111 & amp; 00000001 = 00000001
Sie erhalten true
mit Ihrer bedingten Anweisung.
Es ist erwähnenswert, dass dies in Situationen, in denen Sie Ihre delegate
nur ein- oder zweimal überprüfen müssen, zu viel ist.