Ich schärfe hier: der besondere Fall, den Sie beschreiben, sollte wahrscheinlich nicht auf diese Weise erfolgen. Es ist fast sicher über-clever und sollte wahrscheinlich in viewDidLoad
und viewWillAppear
statt zwei Versionen von viewWillAppear
getrennt werden. Das heißt, das Problem kommt auf.
Meine bevorzugte Lösung ist, eine SEL
zu halten, die auf das zeigt, was ich tun möchte. Zum Beispiel verwende ich diese Art von Technik für eine „nächste Aktion“ nach einer komplizierten asynchronen Aktivität:
if (self.nextActionSelector != NULL)
{
[self performSelector:self.nextActionSelector];
}
Also für diesen, könnten Sie ein viewWillAppearSelector
verwenden, die im Laufe der Zeit geändert werden würde, und viewWillAppear
würde rufen Sie einfach an was auch immer es zeigt auf.
Bens Empfehlung von Method Swizzling ist in einigen Fällen nützlich, aber häufiger, wenn Sie versuchen, das Verhalten eines vorhandenen Objekts anstelle von Ihnen selbst zu ändern. Es kann wirklich Debugging-Spaß machen .... OK, nicht wirklich Spaß. Schmerzlich.Sehr schmerzhaft.
Darüber hinaus würde ich -forwardInvocation:
betrachten, die verwendet werden kann, um auf Nachrichten zu antworten, die Sie nicht direkt implementieren. Sie können den Aufruf dann neu schreiben, um die Methode aufzurufen, die Sie wirklich wollen. Dies ist jedoch nicht die Art, wie es verwendet werden soll. Es dient zum transparenten Weiterleiten von Anrufen an andere Objekte. Aber zumindest ist das Debuggen nicht so schwierig, da der Debugger dort hingeht, wo Sie es erwarten.
Im Allgemeinen suche ich in diesem Fall statt eines Booleschen nach dem Beweis, dass ich schon einmal ausgeführt wurde. Überprüfen, ob view
bereits gesetzt ist, oder ein anderer Wert, der beim ersten Mal initialisiert wird, so dass ich keine spezielle Variable brauche, und ich bin widerstandsfähig gegenüber Dingen, die meinen Zustand löschen (wie das iPhone Dinge bei knappem Speicher ablegt) . Wo immer möglich, mache ich diese Dinge selbst initialisierend in ihren Gettern, anstatt dass eine externe Partei spezielle Erstlogik hat. Die Logik hier einfach zu halten macht die Wartung viel einfacher, und hey, NSInvocation
ist verrückt-langsam (ok, Sie würden es nicht bemerken, außer in einer engen Schleife, aber es ist etwa 500x langsamer als ein Methodenaufruf in meinen Tests. Das sagte Ich schlage nicht vor, diese Entscheidung über die Leistung zu treffen, nur die Wartbarkeit.
Dies ist sehr problematisch für jede Klasse, die kein Singleton ist, da die Nachschlagetabelle nach Klassen und nicht nach Instanzen sortiert ist. Daher wird jedes Swizzling für jede Instanz der Klasse angewendet. – Chuck
Ich stimme mit Chuck überein - Neuzuordnung von Implementierungen in Klassen wird zwangsläufig zu vielen extrem schwierig zu verfolgenden Fehlern führen. Außerdem stimme ich Ihrer Behauptung nicht zu, dass es Code "schwerer zu lesen" macht. Wenn es mit einem der Standardmuster gemacht wird, sollte Code für sogar Junior-Programmierer ziemlich einfach zu lesen sein. Ihre Lösung wird Code viel schwieriger zu grok machen, d. H. "Schwerer zu lesen". –
Können Sie einen Fall beschreiben, in dem der erste drawRect: sich von dem nachfolgenden drawRect unterscheiden sollte: Aufrufe? Wenn Sie Dinge zwischenspeichern, cachen Sie sie in ihren Getter, nicht in drawRect :. Da eine Ansicht ein- und ausgeschaltet werden kann, ist nicht einmal genau klar, was der "erste" Aufruf zu drawRect bedeutet. Erstes Mal für den Unterricht? Zum ersten Mal zum Beispiel? Das erste Mal, seit wir auf den Bildschirm gebracht wurden? Das erste Mal, seit die Ansicht geladen wurde (was mehr als einmal passieren kann) Hast du ein konkretes Beispiel, dass du angreifst? –