Sieht so aus, als müssten Sie explizit definieren, dass der Closure entkommen darf.
Aus der Apple Developer-Dokumentation ,
Eine Closure soll eine Funktion verlassen, wenn die Closure als Argument für die Funktion übergeben wird. Sie wird jedoch aufgerufen, nachdem die Funktion zurückgegeben wurde. Wenn Sie eine Funktion deklarieren, die einen Closure als einen ihrer Parameter akzeptiert, können Sie vor dem Typ des Parameters @escaping schreiben, um anzuzeigen, dass der Closure entkommen darf.
TLDR; Fügen Sie das Schlüsselwort @escaping
nach der Vervollständigungsvariablen hinzu:
Ein "fliehender" Verschluss ist ein Verschluss, der den Umfang, in dem er erstellt wurde, überlebt. Entweichende Verschlüsse erfordern besondere Sorgfalt bei der Referenzzählung und der Speicherverwaltung und können schwieriger zu optimieren sein.
Vor Swift 3 wurde als Standard für Schließungen angenommen, dass sie fliehen würden. Dies bedeutete, dass Entwickler Schließungen, die bekanntlich nicht sind, explizit identifizieren mussten, um dem Compiler zu ermöglichen, Optimierungen vorzunehmen. Die Community fand heraus, dass der Compiler in der Tat leicht selbst herausfinden konnte, ob eine Closure auslief oder nicht, und entschied, dass ein aggressiver Ansatz zum Ausstieg zu einem schnelleren Code führen könnte. Das Ergebnis ist, dass jetzt davon ausgegangen wird, dass Closures nicht mehr ausgeführt werden, und Sie müssen Closures kennzeichnen, die mit dem Attribut @escaping
entkommen.
In Ihrem Fall ist der Abschluss, den URLSession.shared.dataTask
annimmt, selbst ein escaping closure. Wenn Sie also einen Abschluss darin verwenden, muss dieser auch als @escaping
markiert werden.
@escaping
ist für alle aufrufenden Methoden infektiös, und der Compiler bestimmt, wann Sie müssen es einschließen.
Betrachten Sie dieses Beispiel (das kompiliert):
%Vor% Dieses modifizierte Beispiel erzeugt jedoch zwei Fehler vom Typ non-escaping parameter may allow it to escape
:
Der Versand auf main bedeutet, dass die dispatchLater
-Methode @escaping
benötigt, und wenn Sie das hinzugefügt haben, erfordert die dispatchSometime
-Methode auch @escaping
, damit das Beispiel kompiliert werden kann.
Allerdings ist das Mitnehmen nur:
@escaping
der Aufrufkette hinzu, bis der Compiler aufhört, sich zu beschweren. weak
mit den erfassten Variablen zu verwenden, da diese zusammen mit dem Block selbst beibehalten werden können." Implikationen
Der wirklich spaßige Fall ist, dass Sie mehrere Methoden anpassen müssen, um das @escaping
Schlüsselwort einzufügen, das den Compiler dazu bringt, sich nicht mehr zu beschweren. Wenn diese Methoden jedoch tatsächlich einem Protokoll entsprechen, müssen die Methoden dieses Protokolls auch das Schlüsselwort @escaping
erhalten, das auch alle anderen Protokollkonformitäten infiziert. Spaß!
Tags und Links ios swift xcode8 completionhandler