Wenn ich Variablen wie weak
in Swift deklariere , erhalte ich manchmal die Fehlermeldung von Xcode:
'schwach' kann nur auf klassen- und klassengebundene Protokolltypen angewendet werden
Ich habe mich nur gefragt, warum das Schlüsselwort weak
nur auf Klassen- und klassengebundene Protokolltypen angewendet werden kann. Was ist der Grund dafür?
weak
nur relevant ist , auf einen Referenzzähler und nur Klassen sind Referenz gezähltAntworten:
weak
ist ein Qualifikationsmerkmal für Referenztypen (im Gegensatz zu Werttypen wiestruct
s und integrierten Werttypen).Mit Referenztypen können Sie mehrere Referenzen auf dasselbe Objekt haben. Das Objekt wird freigegeben, wenn die letzte starke Referenz nicht mehr darauf verweist (schwache Referenzen zählen nicht).
Werttypen hingegen werden kopiert zugewiesen. Die Referenzzählung gilt nicht, daher ist der
weak
Modifikator bei ihnen nicht sinnvoll.quelle
Ein häufiger Grund für diesen Fehler ist, dass Sie Ihr eigenes Protokoll deklariert haben, aber vergessen haben, von Folgendes zu erben
AnyObject
:protocol PenguinDelegate: AnyObject { func userDidTapThePenguin() } class MyViewController: UIViewController { weak var delegate: PenguinDelegate? }
Der obige Code gibt Ihnen den Fehler, wenn Sie vergessen haben, von zu erben
AnyObject
. Der Grund dafür ist, dass diesweak
nur für Referenztypen (Klassen) sinnvoll ist. Sie machen den Compiler also weniger nervös, indem Sie klar angeben, dass das PenguinDelegate für Klassen und nicht für Werttypen bestimmt ist.quelle
NSObjectProtocol
? Zum einen müssen Sie sich nicht mit dem Hinzufügen desweak
Modifikators befassen .weak
ist ein Qualifikationsmerkmal für Referenztypen und macht bei Werttypen keinen Sinn, da Werttypen per Definition nicht schwach sein können. Ein Protokoll kann von Referenztypen und Werttypen übernommen werden. Sie sollten es also so einschränken, dass es nur durch Referenztypen implementiert wird:protocol PenguinDelegate: class { }
Hier beschränken Sie das Protokoll so, dass es nur durchNSObjectProtocol
s implementiert wird , die ebenfalls Referenztypen sind. Aus diesem Grund funktioniert es.protocol PenguinDelegate: class
die nicht von einer Objective-C-Laufzeit abhängt, aber dennoch das Problem löst.protocol PenguinDelegate: class { func userDidTapThePenguin() } class MyViewController: UIViewController { weak var delegate: PenguinDelegate? }
Wenn Sie class nach Ihrem Protokoll eingeben, funktioniert dies ebenfalls und scheint geeigneter zu sein als für NSObjectProtocol.
quelle
Nun, nur für den Fall, dass jemand anderes denkt, dass Sie wie ich alles richtig in Ihrem Code haben, überprüfen Sie, ob Sie das nicht versehentlich durch
:
ein ersetzt haben=
.Hier ist was ich hatte. Es gab mir auch den gleichen Fehler wie oben:
protocol PenguinDelegate: class { func userDidTapThePenguin() } class MyViewController: UIViewController { weak var delegate = PenguinDelegate? }
Aber der richtige Weg ist:
protocol PenguinDelegate: class { func userDidTapThePenguin() } class MyViewController: UIViewController { weak var delegate: PenguinDelegate? }
Sehen Sie den Unterschied? Es dauerte eine Weile, bis ich sah, dass ich anstelle eines Doppelpunkts ein Gleichheitszeichen hatte. Beachten Sie auch, dass ich andere Fehler für dieselbe Zeile erhalten habe, da ich entschieden hatte, dass mein erster Fehler am wahrscheinlichsten das eigentliche Problem ist:
: - <
quelle
Ich finde in einem Fall heraus, dass Sie sogar einen Klassentyp haben, aber trotzdem diese Fehlermeldung erhalten.
Zum Beispiel,
class MyVC: UIViewController { var myText: UITextView = { [weak self] let text = UITextView() // some codes using self return text }() }
Hier wird ein
UITextView
Objekt aus einem anonymen Block als Initialisierung von zurückgegebenvar myText
. Ich habe die gleiche Art von Fehlermeldung erhalten. Um das Problem zu beheben,var
muss das gekennzeichnet sein alslazy
:class MyVC: UIViewController { lasy var myText: UITextView = { [weak self] let text = UITextView() // some codes using self return text }() }
quelle
weak
ist für ARC (Automatic Reference Counting). Es bedeutet, keinen Referenzzähler hinzuzufügen. Also funktioniert es nur fürClass
. In Swift erhalten Sie einen optionalen Wert für die Sicherheit.quelle
Ich habe versucht, Eigenschaften vom Typ String und Array für einen Abschluss zu erfassen. Ich habe folgende Fehler erhalten:
Ich habe eine Weile auf dem Spielplatz gespielt, und es stellte sich heraus, dass es für diese Typen ausreicht, sich selbst einzufangen.
quelle
Ich habe die objektive C-Klasse schnell für eine scrolView verwendet. Ich habe das IBOutlet dieser Bildlaufansicht erstellt. Und beim Kompilieren von Code wurde dieser Fehler angezeigt.
Um dieses Problem zu beheben, importieren Sie diese Klasse in Ihren Bridging-Header
Ich habe Xcode 9.2 mit Swift 3.2 verwendet
quelle
Nur zu Ihrer Information und wer ist nicht aktualisiert. Nachdem der schnelle Vorschlag SE-0156 https://github.com/apple/swift-evolution/blob/master/proposals/0156-subclass-existentials.md implementiert wurde, gibt es in den Swift-Dokumenten "Nur-Klasse-Protokolle" https : //docs.swift.org/swift-book/LanguageGuide/Protocols.html wird jetzt beschrieben, um AnyObject anstelle von class zu verwenden . Es ist also möglich, dass : Klasse in Zukunft veraltet ist.
quelle
weak
Funktioniert nur für den Referenztyp, sodass Xcode einen Fehler meldet, wenn Sie vonstruct
(anstelle vonclass
) anrufen .quelle
"schwach" kann alles anwenden, was von klassen- oder klassengebundenen Protokolltypen geerbt wird
NSObjectProtocol:
Protokoll ViewControllerDelegate: NSObjectProtocol {func getInformation (Wert: String?)}
quelle