it-swarm.com.de

Mehrere Delegierte in iOS

Ich erstelle ein Objekt, das zum Herunterladen von Inhalten für alle meine View-Controller verwendet wird. Das Objekt ist eine Singleton-Instanz und verfügt über eine Rückrufmethode mit empfangenen Daten, sobald der Download abgeschlossen ist. Darüber hinaus verfügt es über eine Delegate-Eigenschaft, sodass es weiß, zu welchem ​​Objekt es nach dem Download zurückgerufen werden soll.

Es gibt mehrere Controller, die diese gemeinsam genutzte Instanz verwenden, und meine Frage lautet, wie Sie zum richtigen Ansichtscontroller zurückrufen können, der den Download angefordert hat.

Mein Ansatz ist die Verwendung der Delegierung, aber das Problem besteht darin, dass das Download-Objekt, da auch andere Ansichtscontroller ihre Delegierten sind, zu jedem Objekt zurückrufen kann und dies schwer zu verfolgen ist.

20
Chris Lin

Ich habe an Projekten gearbeitet, bei denen versucht wurde, mehrere Delegierte zu verwenden, und das ist im Grunde eine schlechte Idee. Das Delegatenmuster besteht aus einer 1: 1-Beziehung zwischen einer Klasse und ihrem Delegaten. Es ist zwar möglich, durch Ein- und Ausschalten der Delegierten ein gewisses Maß an Mehrfachdelegierung zu erreichen, es ist jedoch wahrscheinlicher, dass dies zu unvorhersehbarem Verhalten und Fehlern führt.

Meine Empfehlung wäre zu ändern, wie Sie darüber denken. Sie haben zwei Möglichkeiten, wie ich es sehe:

  1. Wechseln Sie zu einem Beobachtermuster, in dem Sie mehrere Beobachter registrieren können, mit denen Ihre Hauptklasse interagieren kann. Dies ist nützlich, wenn Ihre Beobachter alle dasselbe Protokoll implementieren und Ihre Hauptklasse die Beobachter kennen und mit ihnen interagieren möchte.

  2. Übertragen Sie NSNotifications, um Statusänderungen und Ereignisse anzuzeigen. Hier handelt es sich um einen eher entkoppelten Ansatz, da die Hauptklasse nicht wissen muss, wer zuhört und nicht direkt mit ihnen interagiert. Andere können nach Belieben beginnen und aufhören, benachrichtigt zu werden. Dies hat auch den Vorteil, dass Sie kein separates Protokoll erstellen oder implementieren müssen. Stattdessen registrieren Sie die Klassen, die über Änderungen informiert werden müssen, im NSNotificationCenter, das wiederum das gesamte Routing von Benachrichtigungen für Sie verwaltet.

44
drekka

Es klingt tatsächlich so, als wäre das Delegiertenmuster hier möglicherweise nicht der beste Ansatz.

Ich würde stattdessen NSNotificationCenter untersuchen.

Die Grundidee ist, dass Ihr Singleton, der die Netzverbindung herstellt, eine Benachrichtigung (mit so etwas wie postNotificationName:object:userInfo:) sendet, dass neue Daten verfügbar sind. In dieser Benachrichtigung können Sie ein Dictionary-Objekt (userInfo) übergeben, das die abgerufenen Daten enthält, oder Informationen darüber, welche Teile Ihres Modells aktualisierte Daten enthalten.

Dann können sich Ihre anderen View-Controller registrieren, um diese Benachrichtigungen durch Aufrufen von addObserver:selector:name:object: zu 'beobachten'. Im Allgemeinen rufe ich addObserver auf, wenn ein VC sichtbar wird, und removeObserver, wenn es ausgeblendet oder ausgeblendet wird.

Viel Glück!

11
Chazbot

Delegation scheint nicht die richtige Lösung für dieses Problem zu sein. Wie wäre es, wenn der anfordernde Ansichtscontroller ein Objekt (sein eigenes) und einen Selektor als Abschlussbenachrichtigung für Sie bereitstellen müsste? Natürlich benötigen Sie einen Speicherort für das Objekt und den Selektor, bis der Download abgeschlossen ist. Hoffentlich haben (oder könnten) Sie ein Objekt dafür.

0
Jay Slupesky

ich empfehle eine dieser Möglichkeiten

Beobachter:

wenn Sie Daten verwenden, die Sie einem anderen Objekt mitteilen möchten, sind diese in der Nähe von primitiven Daten. Wenn Sie beispielsweise "NSMutableArray" verwenden, können Sie die Änderung eines Objekts nicht anhand des standardmäßig implementierten Musters mitteilen. Sie müssen mindestens eines für sich selbst implementieren das ist nicht so viel wiederverwendbar

Benachrichtigung

wenn Ihre Interaktion mit dem Zielobjekt (diese müssen informiert werden) in one-way.it ist, bedeutet dies, dass Sie keine Bestätigung oder andere Daten von ihnen zurück benötigen.

delegieren

wenn es zu jedem Zeitschritt ein zu informierendes Objekt gibt.

hinweis: Die Blockverwendung für Erfolg und Misserfolg ist kein Muster für das Senden von Daten, wenn Sie nicht wissen, wann sie wie Netzwerkvorgänge beendet werden oder fehlschlagen

BEARBEITEN: wie erstelle ich eine Benachrichtigung | Multi-Delegate-Fragen und Umsetzung

0
nova

Obwohl ich den meisten Antworten hier zustimme, könnten Sie, wenn Sie tatsächlich mehrere Delegierte erreichen möchten, möglicherweise ein Array von Delegierten deklarieren und Nachrichten an alle Delegierten innerhalb dieses Arrays senden. Wenn Ihr Protokoll über optionale Delegatmethoden verfügt, prüfen Sie dies vor dem Aufrufen mit responds(to aSelector: Selector!) -> Bool (wobei Sie die Speicherverwaltung berücksichtigen, da diese Delegaten im Array stark referenziert sind). Auch hier stimme ich zu, dass mehrere Delegierte wahrscheinlich eine schlechte Idee für die Architektur sind und die Verwendung von Blöcken oder eines Benachrichtigungszentrums besser zu Ihren Anforderungen passen würde.

0