Sollen wir in Swift immer [nicht besessenes Selbst] Innenverschluss verwenden?


467

In der WWDC 2014-Sitzung 403 Intermediate Swift und im Transkript gab es die folgende Folie

Geben Sie hier die Bildbeschreibung ein

Der Sprecher sagte in diesem Fall, wenn wir es dort nicht verwenden [unowned self], wird es ein Speicherverlust sein. Bedeutet das, dass wir immer einen [unowned self]Innenverschluss verwenden sollten?

In Zeile 64 von ViewController.swift der Swift Weather-App verwende ich nicht [unowned self]. Aber ich aktualisiere die Benutzeroberfläche mit einigen @IBOutlets wie self.temperatureund self.loadingIndicator. Es kann in Ordnung sein, weil alle von @IBOutletmir definierten s sind weak. Aber sollten wir aus Sicherheitsgründen immer verwenden [unowned self]?

class TempNotifier {
  var onChange: (Int) -> Void = {_ in }
  var currentTemp = 72
  init() {
    onChange = { [unowned self] temp in
      self.currentTemp = temp
    }
  }
}

Der Bild-Link ist defekt
Daniel Gomez Rico

@ DanielG.R. Danke, ich kann es sehen. i.stack.imgur.com/Jd9Co.png
Jake Lin

2
Sofern ich mich nicht irre, ist das auf der Folie angegebene Beispiel falsch - onChangesollte ein [weak self]Abschluss sein, da es sich um eine öffentliche (interne, aber immer noch) Eigenschaft handelt, sodass ein anderes Objekt den Abschluss abrufen und speichern kann, wobei das TempNotifier-Objekt erhalten bleibt (unbegrenzt, wenn Das benutzende Objekt ließ den onChangeVerschluss nicht los, bis es sieht, dass das TempNotifierweg ist, über seinen eigenen schwachen Verweis auf das TempNotifier) . Wenn var onChange …waren private var onChange …dann [unowned self]wäre richtig. Ich bin mir dessen jedoch nicht 100% sicher. jemand korrigiert mich bitte, wenn ich falsch liege.
Slipp D. Thompson

@Jake Lin `var onChange: (Int) -> Void = {}` Stellen die geschweiften Klammern einen leeren Verschluss dar? das gleiche wie beim Definieren eines leeren Arrays mit []? Ich kann die Erklärung nicht in den Apple-Dokumenten finden.
bibscy

@bibscy Ja, {}ist der leere Abschluss (die Instanz des Abschlusses) als Standard (macht nichts), (Int) -> Voidist die Abschlussdefinition.
Jake Lin

Antworten:


871

Nein, es gibt definitiv Zeiten, in denen Sie nicht verwenden möchten [unowned self]. Manchmal möchten Sie, dass der Verschluss sich selbst erfasst, um sicherzustellen, dass er zum Zeitpunkt des Aufrufs des Verschlusses noch vorhanden ist.

Beispiel: Erstellen einer asynchronen Netzwerkanforderung

Wenn Sie eine asynchrone Netzwerkanfrage machen Sie tun wollen , dass der Verschluss zu halten selffür , wenn die Anforderung abgeschlossen ist . Dieses Objekt wurde möglicherweise anderweitig freigegeben, Sie möchten jedoch weiterhin in der Lage sein, die Anforderung zu bearbeiten.

Wann unowned selfoder verwendenweak self

Das einzige Mal, wo Sie wirklich verwenden möchten [unowned self]oder sind, [weak self]ist, wenn Sie einen starken Referenzzyklus erstellen würden . Ein starker Referenzzyklus liegt vor, wenn es eine Eigentumsschleife gibt, in der sich Objekte gegenseitig besitzen (möglicherweise durch Dritte) und daher niemals freigegeben werden, da beide sicherstellen, dass sie sich gegenseitig halten.

Im speziellen Fall eines Abschlusses müssen Sie nur erkennen, dass jede Variable, auf die darin verwiesen wird, dem Abschluss "gehört". Solange der Verschluss vorhanden ist, sind diese Objekte garantiert vorhanden. Die einzige Möglichkeit, dieses Eigentum zu stoppen, besteht darin, das [unowned self]oder zu tun [weak self]. Wenn also eine Klasse einen Abschluss besitzt und dieser Abschluss einen starken Verweis auf diese Klasse erfasst, haben Sie einen starken Referenzzyklus zwischen dem Abschluss und der Klasse. Dies schließt auch ein, ob die Klasse etwas besitzt, das den Abschluss besitzt.

Speziell im Beispiel aus dem Video

In dem Beispiel auf der Folie TempNotifierbesitzt der Abschluss über die onChangeElementvariable. Wenn sie nicht erklären haben , selfwie unownedwürde die Schließung auch selbst selfeinen starken Referenzzyklus zu schaffen.

Unterschied zwischen unownedundweak

Der Unterschied zwischen unownedund weakbesteht darin, dass dies weakals optional deklariert wird, während dies unownednicht der Fall ist. Wenn Sie es deklarieren, können weakSie den Fall behandeln, dass es irgendwann im Verschluss Null sein könnte. Wenn Sie versuchen, auf eine unownedVariable zuzugreifen , die zufällig Null ist, stürzt das gesamte Programm ab. Verwenden unownedSie diese Variable also nur, wenn Sie sicher sind, dass sie immer verfügbar ist, während der Abschluss vorhanden ist


1
Hallo. Gute Antwort. Ich kämpfe darum, nicht besessenes Selbst zu verstehen. Ein Grund, schwaches Selbst zu benutzen, nur "Selbst wird optional", reicht mir nicht aus. Warum sollte ich speziell "unbesessenes Selbst" verwenden ? Stackoverflow.com/questions/32936264/…

19
@robdashnash, Der Vorteil der Verwendung von nicht besessenem Selbst besteht darin, dass Sie keinen optionalen Code auspacken müssen, der unnötiger Code sein kann, wenn Sie sicher wissen, dass er niemals Null sein wird. Letztendlich wird nicht besessenes Selbst der Kürze halber und vielleicht auch als Hinweis für zukünftige Entwickler verwendet, dass Sie niemals einen Nullwert erwarten.
Drawag

77
Ein Fall für die Verwendung [weak self]in einer asynchronen Netzwerkanforderung befindet sich in einem Ansichtscontroller, in dem diese Anforderung zum Auffüllen der Ansicht verwendet wird. Wenn der Benutzer zurücktritt, müssen wir die Ansicht nicht mehr füllen und benötigen auch keinen Verweis auf den Ansichts-Controller.
David James

1
weakVerweise werden auch auf gesetzt, nilwenn die Zuordnung des Objekts aufgehoben wird. unownedReferenzen sind nicht.
BergQuester

1
Ich bin etwas verwirrt. unownedwird verwendet, non-Optionalwährend verwendet weakwird, Optionaldamit unser selfist Optionaloder non-optional?
Muhammad Nayab

193

Update 11/2016

Ich habe einen Artikel darüber geschrieben, in dem diese Antwort erweitert wurde (ich habe in SIL nachgesehen, um zu verstehen, was ARC tut). Lesen Sie ihn hier .

Ursprüngliche Antwort

Die vorherigen Antworten geben nicht wirklich einfache Regeln darüber, wann und warum sie übereinander verwendet werden sollen. Lassen Sie mich daher einige Dinge hinzufügen.

Die nicht besessene oder schwache Diskussion läuft auf eine Frage der Lebensdauer der Variablen und des Verschlusses hinaus, der darauf verweist.

schnell schwach gegen nicht besessen

Szenarien

Sie können zwei mögliche Szenarien haben:

  1. Der Verschluss hat die gleiche Lebensdauer der Variablen, sodass der Verschluss nur erreichbar ist , bis die Variable erreichbar ist . Die Variable und der Verschluss haben die gleiche Lebensdauer. In diesem Fall sollten Sie die Referenz als nicht besessen deklarieren . Ein häufiges Beispiel ist das [unowned self]in vielen Beispielen verwendete Beispiel für kleine Verschlüsse, die etwas im Kontext ihrer Eltern tun und auf die nirgendwo anders verwiesen wird, die ihre Eltern nicht überleben.

  2. Die Verschlusslebensdauer ist unabhängig von der der Variablen. Auf den Verschluss kann immer noch verwiesen werden, wenn die Variable nicht mehr erreichbar ist. In diesem Fall sollten Sie die Referenz als schwach deklarieren und sicherstellen, dass sie nicht Null ist, bevor Sie sie verwenden (erzwingen Sie nicht das Auspacken). Ein häufiges Beispiel hierfür ist das Beispiel, das [weak delegate]Sie in einigen Beispielen für das Schließen eines völlig unabhängigen (lebenslangen) Delegatenobjekts sehen können.

Tatsächliche Verwendung

Also, welche werden / sollten Sie eigentlich die meiste Zeit verwenden?

Zitat von Joe Groff von Twitter :

Unbesessen ist schneller und ermöglicht Unveränderlichkeit und Nichtoptionalität.

Wenn Sie nicht schwach brauchen, verwenden Sie es nicht.

Sie werden mehr über unowned finden *Innenleben hier .

* Wird normalerweise auch als nicht besessen (sicher) bezeichnet, um anzuzeigen, dass Laufzeitprüfungen (die zu einem Absturz auf ungültige Referenzen führen) durchgeführt werden, bevor auf die nicht besessene Referenz zugegriffen wird.


26
Ich bin es leid, die Erklärung des Papageien zu hören: "Benutze Woche, wenn das Selbst Null sein könnte, benutze Unbesitz, wenn es niemals Null sein kann." Ok, wir haben es verstanden - millionenfach gehört! Diese Antwort geht tatsächlich tiefer, wann das Selbst im Klartext gleich Null sein kann, was die Frage des OP direkt beantwortet. Danke für diese tolle Erklärung !!
TruMan1

Danke @ TruMan1, ich schreibe gerade einen Beitrag dazu, der bald in meinem Blog landen wird und die Antwort mit einem Link aktualisiert.
Umberto Raimondi

1
Schöne Antwort, sehr praktisch. Ich bin inspiriert, einige meiner leistungsempfindlichen schwachen Vars jetzt auf nicht besessen zu stellen.
original_username

"Die Verschlusslebensdauer ist unabhängig von der der Variablen" Haben Sie hier einen Tippfehler?
Honig

1
Wenn ein Abschluss immer die gleiche Lebensdauer wie das übergeordnete Objekt hat, wird der Referenzzähler dann nicht trotzdem berücksichtigt, wenn das Objekt zerstört wird? Warum kannst du in dieser Situation nicht einfach 'Selbst' benutzen, anstatt dich mit Unbesitz oder Schwäche zu beschäftigen?
LegendLength

105

Ich dachte, ich würde einige konkrete Beispiele speziell für einen View Controller hinzufügen. Viele der Erklärungen, nicht nur hier zu Stack Overflow, sind wirklich gut, aber ich arbeite besser mit Beispielen aus der Praxis (@drewag hatte einen guten Anfang damit):

  • Wenn Sie einen Abschluss haben, um eine Antwort von Netzwerkanforderungen zu verarbeiten, verwenden Sie diese weak, da sie langlebig sind. Der Ansichtscontroller kann geschlossen werden, bevor die Anforderung abgeschlossen ist, sodass selfbeim Aufruf des Abschlusses nicht mehr auf ein gültiges Objekt verweist.
  • Wenn Sie einen Abschluss haben, der ein Ereignis auf einer Schaltfläche behandelt. Dies kann daran liegen unowned, dass die Schaltfläche und alle anderen Elemente, auf die verwiesen wird, gleichzeitig verschwinden, sobald der Ansichts-Controller ausgeblendet selfwird. Gleichzeitig verschwindet auch der Verschlussblock.

    class MyViewController: UIViewController {
          @IBOutlet weak var myButton: UIButton!
          let networkManager = NetworkManager()
          let buttonPressClosure: () -> Void // closure must be held in this class. 
    
          override func viewDidLoad() {
              // use unowned here
              buttonPressClosure = { [unowned self] in
                  self.changeDisplayViewMode() // won't happen after vc closes. 
              }
              // use weak here
              networkManager.fetch(query: query) { [weak self] (results, error) in
                  self?.updateUI() // could be called any time after vc closes
              }
          }
          @IBAction func buttonPress(self: Any) {
             buttonPressClosure()
          }
    
          // rest of class below.
     }

17
Dieser braucht mehr Upvotes. Zwei solide Beispiele, die zeigen, wie ein Tastendruck außerhalb der Lebensdauer des View Controllers nicht vorhanden ist und daher nicht besessene verwenden kann, aber die meisten Netzwerkanrufe, die die Benutzeroberfläche aktualisieren, müssen schwach sein.
Tim Fuqua

2
Verwenden wir zur Verdeutlichung immer Unbesitz oder Schwäche, wenn wir uns in einem Schließungsblock aufrufen? Oder gibt es eine Zeit, in der wir nicht als schwach / nicht besessen bezeichnen? Wenn ja, könnten Sie auch dafür ein Beispiel liefern?
luke

Ich danke dir sehr.
Shawn Baek

1
Dies gab mir ein tieferes Verständnis für [schwaches Selbst] und [nicht besessenes Selbst]. Vielen Dank @possen!
Tommy

Das ist toll. Was ist, wenn ich eine Animation habe , die auf Benutzerinteraktion basiert, deren Fertigstellung jedoch eine Weile dauert? Anschließend wechselt der Benutzer zu einem anderen viewController. Ich denke in diesem Fall sollte ich immer noch weakeher verwenden als unownedrichtig?
Honey

67

Wenn das Selbst im Verschluss gleich Null sein könnte, benutze [schwaches Selbst] .

Wenn das Selbst im Verschluss niemals Null sein wird, verwenden Sie [nicht besessenes Selbst] .

Die Apple Swift-Dokumentation enthält einen großartigen Abschnitt mit Bildern, in denen der Unterschied zwischen der Verwendung von starken , schwachen und nicht besessenen Verschlüssen erläutert wird :

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html


50

Hier sind brillante Zitate aus Apple Developer Forums, die köstliche Details beschreiben:

unownedvs unowned(safe)vsunowned(unsafe)

unowned(safe)ist eine nicht besitzende Referenz, die beim Zugriff bestätigt, dass das Objekt noch aktiv ist. Es ist wie eine schwache optionale Referenz, die bei x!jedem Zugriff implizit entpackt wird. unowned(unsafe)ist wie __unsafe_unretainedin ARC - es ist eine nicht besitzende Referenz, aber es gibt keine Laufzeitprüfung, ob das Objekt beim Zugriff noch aktiv ist, sodass baumelnde Referenzen in den Müllspeicher gelangen. unownedist immer ein Synonym für unowned(safe)aktuell, aber die Absicht ist, dass es unowned(unsafe)in -Ofast Builds optimiert wird, wenn Laufzeitprüfungen deaktiviert sind.

unowned vs. weak

unownedverwendet tatsächlich eine viel einfachere Implementierung als weak. Native Swift-Objekte tragen zwei Referenzzähler, und unowned Referenzen erhöhen den nicht besessenen Referenzzähler anstelle des starken Referenzzählers . Das Objekt wird deinitialisiert, wenn sein starker Referenzzähler Null erreicht, aber es wird erst dann freigegeben, wenn der nicht besessene Referenzzähler ebenfalls Null erreicht. Dies führt dazu, dass der Speicher etwas länger gehalten wird, wenn nicht besessene Referenzen vorhanden sind. Dies ist jedoch normalerweise kein Problem, wennunowned wird verwendet, weil die zugehörigen Objekte ohnehin eine nahezu gleiche Lebensdauer haben sollten, und es ist viel einfacher und kostengünstiger als die auf Seitentabellen basierende Implementierung, die zum Nullstellen schwacher Referenzen verwendet wird.

Update: In der modernen Swift weakintern verwendet den gleichen Mechanismus wie unownedtut . Dieser Vergleich ist also falsch, weil er Objective-C weakmit Swift vergleicht unonwed.

Gründe dafür

Was ist der Zweck, um den Speicher am Leben zu erhalten, nachdem Referenzen 0 erreicht haben? Was passiert, wenn Code versucht, mit dem Objekt mithilfe einer nicht besessenen Referenz etwas zu tun, nachdem es deinitialisiert wurde?

Der Speicher wird am Leben gehalten, so dass seine Aufbewahrungszahlen weiterhin verfügbar sind. Wenn jemand versucht, eine starke Referenz auf das nicht besessene Objekt beizubehalten, kann die Laufzeit auf diese Weise überprüfen, ob die Anzahl der starken Referenzen größer als Null ist, um sicherzustellen, dass das Objekt sicher beibehalten werden kann.

Was passiert mit dem Besitz oder nicht besessenen Referenzen des Objekts? Ist ihre Lebensdauer vom Objekt entkoppelt, wenn es deinitialisiert wird, oder bleibt auch ihr Speicher erhalten, bis die Zuordnung des Objekts aufgehoben wird, nachdem die letzte nicht besessene Referenz freigegeben wurde?

Alle Ressourcen, die dem Objekt gehören, werden freigegeben, sobald die letzte starke Referenz des Objekts freigegeben und dessen Deinit ausgeführt wird. Nicht besessene Referenzen halten nur den Speicher am Leben - abgesehen vom Header mit den Referenzzählern ist sein Inhalt Junk.

Aufgeregt, was?


38

Hier gibt es einige gute Antworten. Die jüngsten Änderungen an der Implementierung schwacher Referenzen durch Swift sollten jedoch die schwachen Selbst- und Nicht-Eigennutzungsentscheidungen aller ändern. Wenn Sie zuvor die beste Leistung mit nicht besessenem Selbst benötigten, war dies dem schwachen Selbst überlegen, solange Sie sicher sein konnten, dass das Selbst niemals Null sein würde, da der Zugriff auf das nicht besessene Selbst viel schneller ist als der Zugriff auf das schwache Selbst.

Mike Ash hat jedoch dokumentiert, wie Swift die Implementierung schwacher Vars aktualisiert hat, um Beistelltische zu verwenden, und wie dies die schwache Selbstleistung erheblich verbessert.

https://mikeash.com/pyblog/friday-qa-2017-09-22-swift-4-weak-references.html

Jetzt, da es keine signifikanten Leistungseinbußen für das schwache Selbst gibt, sollten wir es meiner Meinung nach künftig standardmäßig verwenden. Der Vorteil des schwachen Selbst ist, dass es optional ist, was es viel einfacher macht, korrekteren Code zu schreiben. Dies ist im Grunde der Grund, warum Swift eine so großartige Sprache ist. Sie denken vielleicht, Sie wissen, welche Situationen für die Verwendung von nicht besessenem Selbst sicher sind, aber meine Erfahrung beim Überprüfen vieler anderer Entwicklercodes ist, dass die meisten dies nicht tun. Ich habe viele Abstürze behoben, bei denen nicht freigegebenes Selbst freigegeben wurde, normalerweise in Situationen, in denen ein Hintergrund-Thread abgeschlossen wird, nachdem ein Controller freigegeben wurde.

Fehler und Abstürze sind die zeitaufwändigsten, schmerzhaftesten und teuersten Teile der Programmierung. Geben Sie Ihr Bestes, um den richtigen Code zu schreiben und ihn zu vermeiden. Ich empfehle, es zur Regel zu machen, niemals Auspackoptionen zu erzwingen und niemals ein nicht besessenes Selbst anstelle eines schwachen Selbst zu verwenden. Sie werden nichts verlieren, wenn Sie die Zeiten verpassen, in denen das Auspacken erzwungen wird und das nicht besessene Selbst tatsächlich sicher ist. Aber Sie werden viel davon profitieren, wenn Sie schwer zu findende Abstürze und Fehler beseitigen und Fehler beheben.


Vielen Dank für das Update und Amen zum letzten Absatz.
Motto

1
Also nach den neuen Änderungen Gibt es jemals eine Zeit, in der weaknicht anstelle einer verwendet werden kann unowned?
Honey

4

Laut Apple-Doc

  • Schwache Referenzen sind immer optional und werden automatisch null, wenn die Instanz, auf die sie verweisen, freigegeben wird.

  • Wenn die erfasste Referenz niemals Null wird, sollte sie immer als nicht besessene Referenz und nicht als schwache Referenz erfasst werden

Beispiel -

    // if my response can nil use  [weak self]
      resource.request().onComplete { [weak self] response in
      guard let strongSelf = self else {
        return
      }
      let model = strongSelf.updateModel(response)
      strongSelf.updateUI(model)
     }

    // Only use [unowned self] unowned if guarantees that response never nil  
      resource.request().onComplete { [unowned self] response in
      let model = self.updateModel(response)
      self.updateUI(model)
     }

0

Wenn keiner der oben genannten Punkte Sinn macht:

tl; dr

Genau wie ein implicitly unwrapped optional, wenn du kannst garantieren , dass der Verweis nicht an ihrem Verwendungspunkt Null sein wird, verwenden unowned. Wenn nicht, sollten Sie schwach verwenden.

Erläuterung:

Ich habe Folgendes unter folgender Adresse abgerufen: schwacher, nicht besessener Link . Nach allem, was ich gesammelt habe, kann nicht besessenes Selbst nicht Null sein, aber schwaches Selbst kann es sein, und nicht besessenes Selbst kann zu baumelnden Zeigern führen ... etwas, das in Objective-C berüchtigt ist. Ich hoffe es hilft

"UNOWNED Schwache und nicht besessene Referenzen verhalten sich ähnlich, sind aber NICHT gleich."

Nicht besessene Referenzen erhöhen wie schwache Referenzen nicht die Anzahl der Aufbewahrungen des Objekts, auf das verwiesen wird. In Swift hat eine nicht im Besitz befindliche Referenz jedoch den zusätzlichen Vorteil, dass sie nicht optional ist . Dies erleichtert die Verwaltung, anstatt die optionale Bindung zu verwenden. Dies ist nicht anders als implizit nicht verpackte Optionen. Darüber hinaus sind nicht besessene Referenzen nicht Null . Dies bedeutet, dass beim Freigeben des Objekts der Zeiger nicht auf Null gesetzt wird. Dies bedeutet, dass die Verwendung nicht besessener Referenzen in einigen Fällen zu baumelnden Zeigern führen kann. Für Sie Nerds da draußen, die sich wie ich an die Objective-C-Tage erinnern, werden nicht besessene Referenzen unsicheren_unretained Referenzen zugeordnet.

Hier wird es etwas verwirrend.

Schwache und nicht besessene Referenzen erhöhen nicht die Anzahl der Retentionen.

Sie können beide verwendet werden, um Haltezyklen zu unterbrechen. Wann verwenden wir sie?!

Laut Apples Dokumenten :

„Verwenden Sie eine schwache Referenz, wenn es gültig ist , dass diese Referenz irgendwann während ihrer Lebensdauer Null wird. Verwenden Sie umgekehrt eine nicht im Besitz befindliche Referenz, wenn Sie wissen, dass die Referenz niemals Null sein wird, wenn sie während der Initialisierung festgelegt wurde. “


0
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let controller = storyboard.instantiateViewController(withIdentifier: "AnotherViewController")
        self.navigationController?.pushViewController(controller, animated: true)

    }

}



import UIKit
class AnotherViewController: UIViewController {

    var name : String!

    deinit {
        print("Deint AnotherViewController")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        print(CFGetRetainCount(self))

        /*
            When you test please comment out or vice versa

         */

//        // Should not use unowned here. Because unowned is used where not deallocated. or gurranted object alive. If you immediate click back button app will crash here. Though there will no retain cycles
//        clouser(string: "") { [unowned self] (boolValue)  in
//            self.name = "some"
//        }
//


//
//        // There will be a retain cycle. because viewcontroller has a strong refference to this clouser and as well as clouser (self.name) has a strong refferennce to the viewcontroller. Deint AnotherViewController will not print
//        clouser(string: "") { (boolValue)  in
//            self.name = "some"
//        }
//
//


//        // no retain cycle here. because viewcontroller has a strong refference to this clouser. But clouser (self.name) has a weak refferennce to the viewcontroller. Deint AnotherViewController will  print. As we forcefully made viewcontroller weak so its now optional type. migh be nil. and we added a ? (self?)
//
//        clouser(string: "") { [weak self] (boolValue)  in
//            self?.name = "some"
//        }


        // no retain cycle here. because viewcontroller has a strong refference to this clouser. But clouser nos refference to the viewcontroller. Deint AnotherViewController will  print. As we forcefully made viewcontroller weak so its now optional type. migh be nil. and we added a ? (self?)

        clouser(string: "") {  (boolValue)  in
            print("some")
            print(CFGetRetainCount(self))

        }

    }


    func clouser(string: String, completion: @escaping (Bool) -> ()) {
        // some heavy task
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
            completion(true)
        }

    }

}

Wenn Sie sich nicht sicher sind, [unowned self] verwenden Sie [weak self]

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.