Schnelle schreibgeschützte externe, schreibgeschützte interne Eigenschaft

103

Was ist in Swift die herkömmliche Methode, um das allgemeine Muster zu definieren, bei dem eine Eigenschaft extern schreibgeschützt, aber intern von der Klasse (und den Unterklassen), die sie besitzen, geändert werden kann.

In Objective-C gibt es folgende Optionen:

  • Deklarieren Sie die Eigenschaft in der Schnittstelle als schreibgeschützt und verwenden Sie eine Klassenerweiterung, um intern auf die Eigenschaft zuzugreifen. Dies ist ein nachrichtenbasierter Zugriff, daher funktioniert er gut mit KVO, Atomizität usw.
  • Deklarieren Sie die Eigenschaft in der Schnittstelle als schreibgeschützt, greifen Sie jedoch intern auf den Hintergrund ivar zu. Da der Standardzugriff für ein ivar geschützt ist, funktioniert dies gut in einer Klassenhierarchie, in der Unterklassen auch den Wert ändern können, das Feld jedoch ansonsten schreibgeschützt ist.

In Java lautet die Konvention:

  • Deklarieren Sie ein geschütztes Feld und implementieren Sie einen öffentlichen schreibgeschützten Getter (Methode).

Was ist die Redewendung für Swift?

Jasper Blues
quelle

Antworten:

217

Bei einer gegebenen Klasseneigenschaft können Sie eine andere Zugriffsebene angeben, indem Sie der Eigenschaftsdeklaration den Zugriffsmodifikator gefolgt von getoder setzwischen Klammern voranstellen. Beispielsweise wird eine Klasseneigenschaft mit einem öffentlichen Getter und einem privaten Setter wie folgt deklariert:

private(set) public var readonlyProperty: Int

Empfohlene Lektüre: Getter und Setter

Martins Überlegungen zur Barrierefreiheit sind weiterhin gültig - dh es gibt keinen protectedModifikator, der internalden Zugriff nur auf das Modul, nur privateauf die aktuelle Datei und publicohne Einschränkungen einschränkt.

Schnelle 3 Noten

2 neue Zugriffsmodifikatoren, fileprivateund openwurden in die Sprache hinzugefügt, während privateund publichaben sich leicht geändert:

  • openGilt nur für Klassen und Klassenmitglieder: Hiermit kann eine Klasse untergeordnet oder ein Mitglied außerhalb des Moduls überschrieben werden, in dem sie definiert sind. publicmacht stattdessen die Klasse oder das Mitglied öffentlich zugänglich, aber nicht vererbbar oder überschreibbar

  • privateJetzt wird ein Mitglied nur über die beiliegende Deklaration sichtbar und zugänglich, während es fileprivatefür die gesamte Datei, in der es enthalten ist, zugänglich ist

Weitere Details hier .

Antonio
quelle
Nett! (Ich habe mir erlaubt, das fehlende varSchlüsselwort hinzuzufügen , damit es kompiliert wird.)
Martin R
oh vielen dank :) Ich kopiere normalerweise vom Spielplatz und füge es ein, aber diesmal habe ich es wahrscheinlich falsch gemacht.
Antonio
10
Beachten Sie, dass diese Syntax ab Januar 2015 nicht ganz richtig ist, wenn die äußere Klasse nicht public- es sollte internaloder gar nichts sein (was standardmäßig die Klasse ist - publicoder internal) - dhprivate(set) var readonlyProperty: Int
Grimxn
1
Nun, die Syntax ist korrekt, wenn man bedenkt, dass ich kurz vor dem Code eine Klasseneigenschaft mit einem öffentlichen Getter und einem privaten Setter geschrieben habe - dies ist nur ein Beispiel. Aber ja, Zugriffsmodifikatoren für Eigenschaften müssen mit dem Zugriffsmodifikator class / struct "kompatibel" sein.
Antonio
In Bezug auf den letzten Absatz hat sich dies vermutlich geändert, seit die Antwort geschrieben wurde, privatebeschränkt sich aber jetzt auf den aktuellen Deklaration (nicht auf die Datei) und fileprivatekann auf die aktuelle Datei beschränkt werden. Hat publicauch einige Einschränkungen und openwird für keine Einschränkungen benötigt. Details hier .
Nigel B. Peck
2

Gemäß @Antonio können wir eine einzelne Eigenschaft verwenden, um readOnlyöffentlich und readWriteprivat auf den Eigenschaftswert zuzugreifen . Unten ist meine Illustration:

class MyClass {

    private(set) public var publicReadOnly: Int = 10

    //as below, we can modify the value within same class which is private access
    func increment() {
        publicReadOnly += 1
    }

    func decrement() {
        publicReadOnly -= 1
    }
}

let object = MyClass()
print("Initial  valule: \(object.publicReadOnly)")

//For below line we get the compile error saying : "Left side of mutating operator isn't mutable: 'publicReadOnly' setter is inaccessible"
//object.publicReadOnly += 1

object.increment()
print("After increment method call: \(object.publicReadOnly)")

object.decrement()
print("After decrement method call: \(object.publicReadOnly)")

Und hier ist die Ausgabe:

  Initial  valule: 10
  After increment method call: 11
  After decrement method call: 10
Santosh
quelle