2016-07-23 23 views
6

Laut Apple-Dokument zu NSOperation müssen wir die Methode main für nicht gleichzeitige Operationen und start Methode für gleichzeitige Operationen überschreiben. Aber warum?NSOperation, Start gegen Haupt

Antwort

0

Ich würde davon ausgehen, dass die gleichzeitige vs. nicht gleichzeitig irgendwo nicht nur ein Flag ist aber ein sehr wesentlicher Unterschied. Wenn Sie zwei verschiedene Methoden verwenden, wird absolut sichergestellt, dass Sie keine gleichzeitige Operation verwenden, bei der Sie eine nicht gleichzeitige verwenden sollten oder umgekehrt.

Wenn Sie es falsch ist, wird Ihr Code absolut nicht wegen dieses Design arbeiten. Das ist was du willst, weil du es sofort reparierst. Wenn es nur eine Methode gäbe, würde die Verwendung von gleichzeitigem statt nicht-gleichzeitigem Auftreten zu sehr subtilen Fehlern führen, die sehr schwer zu finden sind. Und nicht-gleichzeitige statt gleichzeitige führt zu Leistungsproblemen, die Sie auch verpassen könnten.

+0

Ich denke, nach Hauptbeendigungen setzt es "isFinished" wahr. Es könnte einer der Gründe sein. – Anshu

+0

Diese Antwort scheint anzunehmen, dass "gleichzeitig" bedeutet "läuft im Hintergrund" oder etwas Ähnliches. Dies ist nicht das, was "gleichzeitig" in NSOperation bedeutet. Gleichzeitige und nicht gleichzeitig ablaufende Vorgänge können beide im Hintergrund ausgeführt werden (und auch die "subtilen Fehler", die Sie aufgrund von Multi-Threading-Verstößen erwähnen). Wenn sie ohne eine Warteschlange ausgeführt werden, können beide vollständig synchron sein. Wenn sie mit einer Queue (seit 10.6) ausgeführt werden, werden beide auf einem Hintergrund-Thread ausgeführt. Der Standard 'start' ruft' main' auf. Gleichzeitige Operationen müssen 'start' überschreiben (der Standard führt nicht gleichzeitiges Verhalten aus). Das ist die Ursache für den Unterschied. –

8

Zunächst einmal daran denken, dass "gleichzeitig" und "nicht gleichzeitig" in NSOperation etwas spezielle Bedeutungen haben, die Leute verwirren (und synonym mit "asynchron/synchron" verwendet werden). "Concurrent" bedeutet, dass die Operation ihre eigene Nebenläufigkeit und ihren eigenen Zustand verwaltet. "Nicht gleichzeitig" bedeutet "die Operation erwartet etwas anderes, normalerweise eine Warteschlange, um ihre Nebenläufigkeit zu verwalten, und möchte die Standardstatusbehandlung."

start macht die ganze Standardzustand Handhabung. Ein Teil davon ist, dass es setzt isExecuting, dann ruft main und wenn main zurückkehrt, es löscht isExecuting und setzt isFinished. Da Sie Ihren eigenen Status bearbeiten, möchten Sie das nicht (Sie möchten nicht beenden main, um den Vorgang zu beenden). Sie müssen also Ihre eigene start implementieren und nicht super aufrufen. Nun könnte man noch eine main Methode haben, wenn man wollte, aber da Sie bereits sind zwingende start (und das ist das, was die Anrufe main), nur die meisten Leute den Code alle in start setzen.

Verwenden Sie in der Regel keine gleichzeitigen Operationen. Sie sind selten was du meinst. Sie definitiv bedeuten nicht "Dinge, die im Hintergrund laufen." Beide Arten von Operationen können im Hintergrund ausgeführt werden (und hat, um im Hintergrund zu laufen). Die Frage ist, ob Sie das Verhalten des Standardsystems (nicht gleichzeitig) wünschen oder ob Sie alles selbst (gleichzeitig) behandeln wollen.

Wenn Ihre Idee, es selbst zu behandeln, "Spin-Up NSThread" ist, machen Sie es fast sicher falsch (es sei denn, Sie tun dies zu Schnittstelle mit einer C/C++ - Bibliothek, die es erfordert). Wenn Sie eine Warteschlange erstellen, tun Sie wahrscheinlich Fehler (NSOperation verfügt über alle möglichen Funktionen, um dies zu vermeiden). Wenn es so gut wie alles ist, was so aussieht, als würde man "Dinge manuell im Hintergrund erledigen", macht man es wahrscheinlich falsch. Das standardmäßige (nicht gleichzeitige) Verhalten ist fast sicher besser als das, was Sie tun werden.

Wo gleichzeitige Operationen nützlich sein kann, ist in den Fällen, dass die API Sie verwenden für Sie bereits behandelt Gleichzeitigkeit. Eine nicht gleichzeitige Operation endet, wenn main zurückkehrt. Was ist, wenn Ihre Operation eine asynchrone Sache wie NSURLConnection umschließt? Eine Möglichkeit, dies zu umgehen, besteht darin, eine Versandgruppe zu verwenden und dann dispatch_wait am Ende Ihrer main anzurufen, damit es erst zurückkehrt, wenn alles erledigt ist. Das ist ok. Das mache ich die ganze Zeit. Aber es blockiert einen Thread, der sonst nicht blockiert wäre, was einige Ressourcen verschwendet und in einigen aufwendigen Fällen zu einem Deadlock führen könnte. Apple behauptet, es sei möglich und sie haben es gesehen, aber ich war noch nie in der Lage, es sogar absichtlich geschehen zu lassen).

Eine andere Möglichkeit, wie Sie es tun können, ist, sich als eine gleichzeitige Operation zu definieren, und setzen isFinished von Hand in Ihre NSURLConnection Delegate-Methoden. Ähnliche Situationen treten auf, wenn Sie andere asynchrone Schnittstellen wie Dispatch I/O umschließen und gleichzeitige Operationen dafür effizienter sein können.

(In der Theorie können gleichzeitige Operationen auch nützlich sein, wenn Sie eine Operation ausführen möchten, ohne eine Warteschlange zu verwenden. Ich kann mir einige sehr komplizierte Fälle vorstellen, in denen dies sinnvoll ist, aber es ist eine Strecke, und wenn Sie sind in diesem Boot, ich nehme an, Sie wissen, was Sie tun.)

Aber wenn Sie überhaupt eine Frage haben, verwenden Sie einfach das Standard-Verhalten nicht-contrurent. Sie können fast immer das gewünschte Verhalten mit wenig Aufwand erreichen (besonders, wenn Sie eine Dispatch-Gruppe verwenden), und dann müssen Sie sich nicht mit der etwas verwirrenden Erklärung von "gleichzeitig" in den Dokumenten beschäftigen.