Hat Swift Zugriffsmodifikatoren?

273

In Objective-C können beispielsweise Daten sein public, protectedoder private. Zum Beispiel:

@interface Foo : NSObject
{
  @public
    int x;
  @protected:
    int y;
  @private:
    int z;
  }
-(int) apple;
-(int) pear;
-(int) banana;
@end

Ich habe in der Swift-Referenz keine Erwähnung von Zugriffsmodifikatoren gefunden. Ist es möglich, die Sichtbarkeit von Daten in Swift einzuschränken?

Gergo Erdosi
quelle
Ich auch nicht. Apple sollte zumindest die Etikette für Privatpersonen einführen, wie in Python wird ihnen ein Unterstrich vorangestellt.
Ciantic
Es wurde eine Antwort hinzugefügt, die für die endgültige Version von Xcode 6.1.1
holroy
Swift 4 aktualisierte Antwort .
Ahmad F

Antworten:

419

Ab Swift 3.0.1 gibt es 4 Zugriffsebenen , die im Folgenden von der höchsten (am wenigsten einschränkenden) bis zur niedrigsten (am meisten einschränkenden) beschrieben werden.


1. openundpublic

Aktivieren Sie die Verwendung einer Entität außerhalb des definierenden Moduls (Ziels). Sie verwenden openoder publicgreifen normalerweise zu, wenn Sie die öffentliche Schnittstelle zu einem Framework angeben.

Der openZugriff gilt jedoch nur für Klassen und Klassenmitglieder und unterscheidet sich vom publicZugriff wie folgt:

  • public Klassen und Klassenmitglieder können nur innerhalb des definierenden Moduls (Ziels) untergeordnet und überschrieben werden.
  • open Klassen und Klassenmitglieder können sowohl innerhalb als auch außerhalb des definierenden Moduls (Ziels) in Unterklassen unterteilt und überschrieben werden.

// First.framework – A.swift

open class A {}

// First.framework – B.swift

public class B: A {} // ok

// Second.framework – C.swift

import First

internal class C: A {} // ok

// Second.framework – D.swift

import First

internal class D: B {} // error: B cannot be subclassed

2. internal

Ermöglicht die Verwendung einer Entität innerhalb des definierenden Moduls (Ziels). Normalerweise verwenden Sie den internalZugriff, wenn Sie die interne Struktur einer App oder eines Frameworks definieren.

// First.framework – A.swift

internal struct A {}

// First.framework – B.swift

A() // ok

// Second.framework – C.swift

import First

A() // error: A is unavailable

3. fileprivate

Beschränkt die Verwendung einer Entität auf die definierende Quelldatei. Normalerweise verwenden Sie den fileprivateZugriff, um die Implementierungsdetails einer bestimmten Funktionalität auszublenden, wenn diese Details in einer gesamten Datei verwendet werden.

// First.framework – A.swift

internal struct A {

    fileprivate static let x: Int

}

A.x // ok

// First.framework – B.swift

A.x // error: x is not available

4. private

Beschränkt die Verwendung einer Entität auf die beigefügte Deklaration. Normalerweise verwenden Sie den privateZugriff, um die Implementierungsdetails einer bestimmten Funktionalität auszublenden, wenn diese Details nur in einer einzelnen Deklaration verwendet werden.

// First.framework – A.swift

internal struct A {

    private static let x: Int

    internal static func doSomethingWithX() {
        x // ok
    }

}

A.x // error: x is unavailable
akashivskyy
quelle
37
Könnte mir jemand erklären, warum das nicht eine große Sache ist?
Zaky German
15
Es gibt immer einige Methoden oder Variablen in OOP, die privat oder geschützt sein sollten. Dies ermöglicht die Implementierung des SOLID-Designs , da große Methoden in eine Reihe kleinerer Methoden unterteilt werden, von denen jede ihre eigene Verantwortung trägt. Diese können überschrieben werden, aber nur die "Haupt" -Methode sollte für die öffentliche Verwendung verfügbar sein.
Akashivskyy
19
Ich persönlich mag keine Lösungen wie die mit den unterstrichenen / speziellen Zeichen, die "private" Methoden führen. Selbst wenn garantiert ist, dass ich für mich die einzige Person bin, die sich diesen Code jemals ansieht, wird der Code dadurch sicherer / weniger fehleranfällig, da der Compiler Sie einfach daran hindert, Dinge zu tun, die Sie nicht tun sollten. Ich denke, sie sollten die "Zugangskontrollmechanismen" so schnell wie möglich verlassen, damit sich die Leute nicht an schlechte Gewohnheiten gewöhnen.
Jonas Eschmann
10
In den Beta-Versionshinweisen zu Xcode 6 heißt es: "Die Zugriffskontrolle (öffentliche / private Mitglieder) ist in diesem Seed nicht aktiviert. (15747445)"
Martin Ullrich
9
@alcalde Die Idee einer öffentlichen Schnittstelle ist sehr wertvoll. Wenn Sie beabsichtigen, dass sich der gesamte Code in einer Klasse in Funktionen befinden muss, die Teil der öffentlichen API sind, ist dies meiner Meinung nach recht einschränkend. Auf der anderen Seite kann die Implementierung durch eine bestimmte öffentliche API geändert werden (einschließlich der Verwendung privater Methoden), ohne die Verbraucher zu stören. Wenn jemand eine interne Klassenmethode "benötigt", habe ich das Gefühl, dass er die Grenzen der Klassenfunktionalität falsch versteht (oder versucht, eine fehlerhafte Klasse zu verwenden).
Jinglesthula
26

Swift 4 / Swift 5

Wie in der Swift-Dokumentation - Zugriffskontrolle erwähnt , verfügt Swift über 5 Zugriffskontrollen :

  • offen und öffentlich : Der Zugriff erfolgt über die Entitäten ihres Moduls und über alle Entitäten des Moduls, die das definierende Modul importieren.

  • intern : kann nur von den Entitäten ihres Moduls aus aufgerufen werden. Dies ist die Standardzugriffsebene.

  • fileprivate und private : Der Zugriff kann nur in begrenztem Umfang innerhalb eines begrenzten Bereichs erfolgen, in dem Sie sie definieren.



Was ist der Unterschied zwischen offen und öffentlich ?

open ist dasselbe wie public in früheren Versionen von Swift. Sie ermöglichen es Klassen aus anderen Modulen, diese zu verwenden und zu erben, dh sie können von anderen Modulen in Unterklassen unterteilt werden. Außerdem können Mitglieder aus anderen Modulen diese verwenden und überschreiben. Die gleiche Logik gilt für ihre Module.

public erlaubt Klassen von anderen Modulen, sie zu verwenden, aber nicht zu erben, dh: Sie können nicht von anderen Modulen in Unterklassen unterteilt werden. Außerdem erlauben sie Mitgliedern aus anderen Modulen, sie zu verwenden, aber NICHT zu überschreiben. Für ihre Module haben sie dieselbe Open-Logik (sie erlauben Klassen, sie zu verwenden und zu erben; sie erlauben Mitgliedern, sie zu verwenden und zu überschreiben).


Was ist der Unterschied zwischen fileprivate und private ?

Auf fileprivate kann von den gesamten Dateien aus zugegriffen werden.

Auf private kann nur über ihre einzelne Deklaration und auf Erweiterungen dieser Deklaration zugegriffen werden , die sich in derselben Datei befinden. Zum Beispiel:

// Declaring "A" class that has the two types of "private" and "fileprivate":
class A {
    private var aPrivate: String?
    fileprivate var aFileprivate: String?

    func accessMySelf() {
        // this works fine
        self.aPrivate = ""
        self.aFileprivate = ""
    }
}

// Declaring "B" for checking the abiltiy of accessing "A" class:
class B {
    func accessA() {
        // create an instance of "A" class
        let aObject = A()

        // Error! this is NOT accessable...
        aObject.aPrivate = "I CANNOT set a value for it!"

        // this works fine
        aObject.aFileprivate = "I CAN set a value for it!"
    }
}



Was sind die Unterschiede zwischen Swift 3 und Swift 4 Access Control?

Wie im SE-0169-Vorschlag erwähnt , wurde Swift 4 nur dahingehend verfeinert , dass der Bereich für die private Zugriffskontrolle erweitert wurde, um über Erweiterungen dieser Erklärung in derselben Datei zugänglich zu sein . Zum Beispiel:

struct MyStruct {
    private let myMessage = "Hello World"
}

extension MyStruct {
    func printMyMessage() {
        print(myMessage)
        // In Swift 3, you will get a compile time error:
        // error: 'myMessage' is inaccessible due to 'private' protection level

        // In Swift 4 it should works fine!
    }
}

Es ist also nicht erforderlich, myMessageals Dateiprivat zu deklarieren , um in der gesamten Datei zugänglich zu sein.

Ahmad F.
quelle
17

Wenn man davon spricht, eine "private Methode" in Swift oder ObjC (oder Ruby oder Java oder ...) zu erstellen, sind diese Methoden nicht wirklich privat. Es gibt keine tatsächliche Zugangskontrolle um sie herum. Jede Sprache, die auch nur ein wenig Selbstbeobachtung bietet, ermöglicht es Entwicklern, diese Werte von außerhalb der Klasse zu erreichen, wenn sie dies wirklich möchten.

Also , was wir wirklich über hier sprechen , ist eine Möglichkeit , eine öffentlich zugängliche Schnittstelle zu definieren , dass lediglich stellt die Funktionalität , die wir es wollen, und „versteckt“ der Rest , dass wir „privat“ in Betracht ziehen.

Der Swift-Mechanismus zum Deklarieren von Schnittstellen ist der protocolund kann für diesen Zweck verwendet werden.

protocol MyClass {
  var publicProperty:Int {get set}
  func publicMethod(foo:String)->String
}

class MyClassImplementation : MyClass {
  var publicProperty:Int = 5
  var privateProperty:Int = 8

  func publicMethod(foo:String)->String{
    return privateMethod(foo)
  }

  func privateMethod(foo:String)->String{
    return "Hello \(foo)"
  }
}

Denken Sie daran, dass Protokolle erstklassige Typen sind und überall dort verwendet werden können, wo ein Typ dies kann. Und wenn sie auf diese Weise verwendet werden, legen sie nur ihre eigenen Schnittstellen offen, nicht die des Implementierungstyps.

Solange Sie MyClassstatt MyClassImplementationin Ihren Parametertypen usw. verwenden, sollte alles nur funktionieren:

func breakingAndEntering(foo:MyClass)->String{
  return foo.privateMethod()
  //ERROR: 'MyClass' does not have a member named 'privateMethod'
}

Es gibt einige Fälle direkter Zuweisung, in denen Sie den Typ explizit angeben müssen, anstatt sich auf Swift zu verlassen, um darauf zu schließen, aber das scheint kaum ein Deal Breaker zu sein:

var myClass:MyClass = MyClassImplementation()

Die Verwendung von Protokollen auf diese Weise ist semantisch, ziemlich präzise und ähnelt in meinen Augen stark den Klassenerweiterungen, die wir für diesen Zweck in ObjC verwendet haben.

jemmons
quelle
1
Wie kann ich eine öffentliche Methode mit optionalen Parametern erstellen, die weiterhin dem Protokoll entspricht, wenn Protokolle kein Standardargument zulassen?
Bdurao
Ich verstehe nicht, was du meinst. Im Folgenden wird eine öffentliche Methode mit einem optionalen Parameter erstellt. Es scheint kein Problem zu geben: gist.github.com/anonymous/17d8d2d25a78644046b6
jemmons
Aus irgendeinem Grund funktioniert der optionale Parameter in meinem Projekt nicht so, wie er sollte. Ich habe bereits etwas Ähnliches wie Ihr GitHub-Beispiel ausprobiert. Da wir für ein Protokoll keinen Standardparameter festlegen können, blieb ich stecken und stellte schließlich eine Frage. Danke, dass Sie versucht haben zu helfen.
Bdurao
Wir alle wissen, dass alles hackbar ist. Wir brauchen nur eine Bestellung, weshalb wir Zugriffsmodifikatoren benötigen
canbax
14

Soweit ich das beurteilen kann, gibt es keine Schlüsselwörter "öffentlich", "privat" oder "geschützt". Dies würde bedeuten, dass alles öffentlich ist.

Apple erwartet jedoch möglicherweise, dass Benutzer „ Protokolle “ (vom Rest der Welt als Schnittstellen bezeichnet) und das werkseitige Entwurfsmuster verwenden , um Details des Implementierungstyps zu verbergen.

Dies ist oft ein gutes Entwurfsmuster, das ohnehin verwendet werden kann. Sie können damit Ihre Implementierungsklassenhierarchie ändern und gleichzeitig das logische Typsystem beibehalten.

Ian Ringrose
quelle
Dies ist schön, da es auch die Kopplung verringert und das Testen erleichtern kann.
Scroog1
4
Das würde besser funktionieren, wenn es eine Möglichkeit gäbe, die Implementierungsklasse des Protokolls zu verbergen, aber es scheint keine zu geben.
David Moles
Kann jemand ein anschauliches Beispiel für dieses Muster liefern?
Bloudermilk
Nun, diese Antwort war in den vorherigen Swift-Versionen gültig, es scheint, dass sie nicht mehr gültig ist :) Bitte überprüfen Sie meine Antwort .
Ahmad F
12

Mit einer Kombination aus Protokollen, Abschlüssen und verschachtelten / inneren Klassen ist es möglich, Informationen in Swift zu verwenden, um Informationen in Swift zu verbergen. Es ist nicht super sauber oder schön zu lesen, aber es funktioniert.

Beispiel:

protocol HuhThing {
  var huh: Int { get set }
}

func HuhMaker() -> HuhThing {
   class InnerHuh: HuhThing {
    var innerVal: Int = 0
    var huh: Int {
      get {
        return mysteriousMath(innerVal)
      }

      set {
       innerVal = newValue / 2
      }
    }

    func mysteriousMath(number: Int) -> Int {
      return number * 3 + 2
    }
  }

  return InnerHuh()
}

HuhMaker()
var h = HuhMaker()

h.huh      // 2
h.huh = 32 
h.huh      // 50
h.huh = 39
h.huh      // 59

innerVal und secretMath sind hier vor äußerer Verwendung verborgen, und der Versuch, sich in das Objekt hineinzuarbeiten, sollte zu einem Fehler führen.

Ich bin nur ein Teil des Weges durch das Lesen der Swift-Dokumente. Wenn es hier also einen Fehler gibt, weisen Sie bitte darauf hin, ich würde es gerne wissen.

Dave Kapp
quelle
ok, ich habe auch über diese lösung nachgedacht, aber erkläre mir, warum ich nicht mit h.huh.innerVal zugreifen kann?
Sam
Swift ist typsicher und das einzige, was die Außenwelt über h weiß, ist, dass es HuhThing entspricht. HuhThing enthält keine Informationen zu einer Eigenschaft namens innerVal. Der Versuch, darauf zuzugreifen, ist daher ein Fehler.
Dave Kapp
8
Noch zugänglich: Preflect(h)[0].1.value // 19
John Estropia
2
Schöner Fund dort John - ich war mir des Nachdenkens nicht bewusst. Scheint Objekte in Tupel zu verwandeln - gibt es eine offizielle Dokumentation zu dieser Funktion oder zu anderen Metaprogrammierungsmaterialien in Swift? Ich habe den Sprachführer auf iBooks durchgesehen, sehe ihn aber nicht.
Dave Kapp
1
@ JohnEstropia Ich denke nicht, dass Reflexion zählt. In Java (einer ausgereifteren Sprache) gibt es Zugriffsmodifikatoren, die jedoch auch Reflexionstricks nicht verhindern.
11684
10

Ab Xcode 6 Beta 4 verfügt Swift über Zugriffsmodifikatoren. Aus den Versionshinweisen:

Die schnelle Zugriffskontrolle verfügt über drei Zugriffsebenen:

  • Auf private Entitäten kann nur aus der Quelldatei zugegriffen werden, in der sie definiert sind.
  • Auf interne Entitäten kann überall innerhalb des Ziels zugegriffen werden, wo sie definiert sind.
  • Auf öffentliche Entitäten kann von überall innerhalb des Ziels und von jedem anderen Kontext aus zugegriffen werden, der das Modul des aktuellen Ziels importiert.

Die implizite Standardeinstellung ist internal, sodass Sie innerhalb eines Anwendungsziels Zugriffsmodifikatoren deaktivieren können, es sei denn, Sie möchten restriktiver sein. Verwenden publicSie in einem Framework-Ziel (z. B. wenn Sie ein Framework einbetten, um Code zwischen einer App und einer Freigabe oder einer Erweiterung der Heute-Ansicht freizugeben), um die API festzulegen, die Sie Clients Ihres Frameworks zur Verfügung stellen möchten.

Rickster
quelle
Nun, diese Antwort war in den vorherigen Swift-Versionen gültig, es scheint, dass sie nicht mehr gültig ist :) Bitte überprüfen Sie meine Antwort .
Ahmad F
6

Swift 3.0 bietet fünf verschiedene Zugriffskontrollen:

  1. öffnen
  2. Öffentlichkeit
  3. intern
  4. fileprivate
  5. Privat

Open Access und Public Access ermöglichen die Verwendung von Entitäten in jeder Quelldatei ihres Definitionsmoduls sowie in einer Quelldatei eines anderen Moduls, das das Definitionsmodul importiert. Normalerweise verwenden Sie offenen oder öffentlichen Zugriff, wenn Sie die öffentliche Schnittstelle zu einem Framework angeben.

Durch den internen Zugriff können Entitäten in jeder Quelldatei ihres definierenden Moduls verwendet werden, jedoch nicht in einer Quelldatei außerhalb dieses Moduls. Normalerweise verwenden Sie den internen Zugriff, wenn Sie die interne Struktur einer App oder eines Frameworks definieren.

Der dateiprivate Zugriff beschränkt die Verwendung einer Entität auf die eigene definierende Quelldatei. Verwenden Sie den dateiprivaten Zugriff, um die Implementierungsdetails einer bestimmten Funktionalität auszublenden, wenn diese Details in einer gesamten Datei verwendet werden.

Der private Zugriff beschränkt die Verwendung einer Entität auf die beigefügte Deklaration. Verwenden Sie den privaten Zugriff, um die Implementierungsdetails einer bestimmten Funktionalität auszublenden, wenn diese Details nur in einer einzelnen Deklaration verwendet werden.

Open Access ist die höchste (am wenigsten einschränkende) Zugriffsebene und Private Access ist die niedrigste (am meisten einschränkende) Zugriffsebene.

Standardzugriffsebenen

Alle Entitäten in Ihrem Code (mit wenigen Ausnahmen) haben eine Standardzugriffsebene von intern, wenn Sie selbst keine explizite Zugriffsebene angeben. In vielen Fällen müssen Sie daher in Ihrem Code keine explizite Zugriffsebene angeben.

Der Versionshinweis zum Thema:

Als öffentlich deklarierte Klassen können nicht mehr außerhalb ihres Definitionsmoduls untergeordnet werden, und als öffentlich deklarierte Methoden können außerhalb ihres Definitionsmoduls nicht mehr überschrieben werden. Um zuzulassen, dass eine Klasse extern untergeordnet oder eine Methode extern überschrieben wird, deklarieren Sie sie als offen. Dies ist eine neue Zugriffsebene außerhalb der Öffentlichkeit. Importierte Objective-C-Klassen und -Methoden werden jetzt alle als offen und nicht als öffentlich importiert. Komponententests, die ein Modul mithilfe eines @ testable-Imports importieren, können weiterhin öffentliche oder interne Klassen unterordnen sowie öffentliche oder interne Methoden überschreiben. (SE-0117)

Weitere Informationen und Details: Die Swift-Programmiersprache (Zugriffskontrolle)

CryingHippo
quelle
Nun, diese Antwort war in den vorherigen Swift-Versionen gültig, es scheint, dass sie nicht mehr gültig ist :) Bitte überprüfen Sie meine Antwort .
Ahmad F
4

In Beta 6 heißt es in der Dokumentation, dass es drei verschiedene Zugriffsmodifikatoren gibt:

  • Öffentlichkeit
  • Intern
  • Privat

Und diese drei gelten für Klassen, Protokolle, Funktionen und Eigenschaften.

public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}

Weitere Informationen finden Sie unter Zugriffssteuerung .

OliverAssad
quelle
Es sollte einen geschützten Modifikator geben, der das Erstellen von Klassen mit größerer Sicherheit erleichtert.
Kumar C
Nun, diese Antwort war in den vorherigen Swift-Versionen gültig, es scheint, dass sie nicht mehr gültig ist :) Bitte überprüfen Sie meine Antwort .
Ahmad F
2

In Beta 4 haben sie Swift Zugriffsmodifikatoren hinzugefügt.

von Xcode 6 Beta 4 Realese Notizen :

Die schnelle Zugriffskontrolle verfügt über drei Zugriffsebenen:

  • private Auf Entitäten kann nur innerhalb der Quelldatei zugegriffen werden, in der sie definiert sind.
  • internal Auf Entitäten kann überall innerhalb des Ziels zugegriffen werden, wo sie definiert sind.
  • public Auf Entitäten kann von überall innerhalb des Ziels und von jedem anderen Kontext aus zugegriffen werden, der das Modul des aktuellen Ziels importiert.

Standardmäßig haben die meisten Entitäten in einer Quelldatei internen Zugriff. Auf diese Weise können Anwendungsentwickler die Zugriffssteuerung weitgehend ignorieren, während Framework-Entwickler die vollständige Kontrolle über die API eines Frameworks haben.

Alexey Globchastyy
quelle
Kannst du einen Link dazu posten?
Schneemann
Nun, diese Antwort war in den vorherigen Swift-Versionen gültig, es scheint, dass sie nicht mehr gültig ist :) Bitte überprüfen Sie meine Antwort .
Ahmad F
2

Zugriffskontrollmechanismen wie in Xcode 6 eingeführt :

Swift bietet drei verschiedene Zugriffsebenen für Entitäten in Ihrem Code. Diese Zugriffsebenen beziehen sich auf die Quelldatei, in der eine Entität definiert ist, und auch auf das Modul, zu dem die Quelldatei gehört.

  • Mit dem öffentlichen Zugriff können Entitäten in jeder Quelldatei ihres Definitionsmoduls sowie in einer Quelldatei eines anderen Moduls verwendet werden, das das Definitionsmodul importiert. Normalerweise verwenden Sie den öffentlichen Zugriff, wenn Sie die öffentliche Schnittstelle zu einem Framework angeben.
  • Durch den internen Zugriff können Entitäten in jeder Quelldatei ihres definierenden Moduls verwendet werden, jedoch nicht in einer Quelldatei außerhalb dieses Moduls. Normalerweise verwenden Sie den internen Zugriff, wenn Sie die interne Struktur einer App oder eines Frameworks definieren.
  • Der private Zugriff beschränkt die Verwendung einer Entität auf die eigene definierende Quelldatei. Verwenden Sie den privaten Zugriff, um die Implementierungsdetails einer bestimmten Funktionalität auszublenden.

Der öffentliche Zugang ist die höchste (am wenigsten einschränkende) Zugriffsebene und der private Zugriff ist die niedrigste (oder am meisten einschränkende) Zugriffsebene.

Die Standardeinstellung ist intern und muss daher nicht angegeben werden. Beachten Sie auch, dass der private Bezeichner nicht auf Klassenebene, sondern auf Quelldateiebene funktioniert. Dies bedeutet, dass Sie Teile einer Klasse in eine eigene Datei trennen müssen, um sie wirklich privat zu machen. Dies führt auch einige interessante Fälle in Bezug auf Unit-Tests ein ...

Ein weiterer Punkt, den ich gemacht habe und der im obigen Link kommentiert wird, ist, dass Sie die Zugriffsebene nicht "aktualisieren" können. Wenn Sie etwas unterordnen, können Sie es stärker einschränken, aber nicht umgekehrt.

Dieses letzte Bit wirkt sich auch auf Funktionen, Tupel und sicherlich andere Dinge aus, so dass es nicht gültig ist, die Funktion intern oder öffentlich zu haben , wenn eine Funktion eine private Klasse verwendet , da sie möglicherweise keinen Zugriff auf die private Klasse haben. Dies führt zu einer Compiler-Warnung, und Sie müssen die Funktion als private Funktion neu deklarieren .

holroy
quelle
Nun, diese Antwort war in den vorherigen Swift-Versionen gültig, es scheint, dass sie nicht mehr gültig ist :) Bitte überprüfen Sie meine Antwort .
Ahmad F
2

Swift 3 und 4 brachten auch für die Zugriffsebenen von Variablen und Methoden viele Änderungen mit sich. Swift 3 und 4 haben jetzt 4 verschiedene Zugriffsebenen, wobei offener / öffentlicher Zugriff die höchste (am wenigsten einschränkende) Zugriffsebene und privater Zugriff die niedrigste (am meisten einschränkende) Zugriffsebene ist:

  • Auf private Funktionen und Mitglieder kann nur im Rahmen der Entität selbst (Struktur, Klasse,…) und ihrer Erweiterungen zugegriffen werden (in Swift 3 wurden auch die Erweiterungen eingeschränkt).
  • Auf dateiprivate Funktionen und Mitglieder kann nur aus der Quelldatei zugegriffen werden, in der sie deklariert sind.
  • Auf interne Funktionen und Mitglieder (dies ist die Standardeinstellung, wenn Sie kein Schlüsselwort für die Zugriffsebene explizit hinzufügen) kann überall innerhalb des Ziels zugegriffen werden, wo sie definiert sind. Aus diesem Grund hat das TestTarget nicht automatisch Zugriff auf alle Quellen. Sie müssen im Dateiinspektor von xCode als zugänglich markiert werden.
  • Auf offene oder öffentliche Funktionen und Mitglieder kann von überall innerhalb des Ziels und von jedem anderen Kontext aus zugegriffen werden, der das Modul des aktuellen Ziels importiert.

Interessant:

Anstatt jede einzelne Methode oder jedes einzelne Mitglied als "privat" zu markieren, können Sie einige Methoden (z. B. normalerweise Hilfsfunktionen) in einer Erweiterung einer Klasse / Struktur behandeln und die gesamte Erweiterung als "privat" markieren.

class foo { }

private extension foo {
    func somePrivateHelperFunction01() { }
    func somePrivateHelperFunction02() { }
    func somePrivateHelperFunction03() { }
}

Dies kann eine gute Idee sein, um besser wartbaren Code zu erhalten. Und Sie können einfach (z. B. zum Testen von Einheiten) auf nicht privat umschalten, indem Sie nur ein Wort ändern.

Apple-Dokumentation

LukeSideWalker
quelle
Nun, diese Antwort war in den vorherigen Swift-Versionen gültig, es scheint, dass sie nicht mehr gültig ist :) Bitte überprüfen Sie meine Antwort .
Ahmad F
2

Für Swift 1-3:

Nein, es ist nicht möglich. Es gibt überhaupt keine privaten / geschützten Methoden und Variablen.

Alles ist öffentlich.

Update Seit Swift 4 können andere Antworten in diesem Thread angezeigt werden

Sam
quelle
1
Dieser Kommentar ist für den aktuellen Startwert korrekt.
Jesper
2
Für den aktuellen Samen. Es wird in Zukunft erscheinen .
Jesper
1
"public" / "protected" / "private" gibt es derzeit nicht, aber Sie können Dinge mithilfe von Closures, Protokollen und inneren Klassen ausblenden. Dies ähnelt in etwa dem in JavaScript häufig verwendeten Modulmuster. In meinem Beispielcode in meiner Antwort finden Sie ein Beispiel dafür. Wenn ich mich irre, wie es funktioniert, und mein Beispiel falsch ist, weisen Sie bitte darauf hin, da ich auch noch lerne. :)
Dave Kapp
Es scheint, dass es nicht mehr gültig ist :) Bitte überprüfen Sie meine Antwort .
Ahmad F
1

Eine der Optionen, die Sie verwenden können, besteht darin, die Instanzerstellung in eine Funktion zu verpacken und die entsprechenden Getter und Setter in einem Konstruktor bereitzustellen:

class Counter {
    let inc: () -> Int
    let dec: () -> Int

    init(start: Int) {
        var n = start

        inc = { ++n }
        dec = { --n }
    }
}


let c = Counter(start: 10)

c.inc()  // 11
c.inc()  // 12
c.dec()  // 11
Bartosz Ciechanowski
quelle
0

Die Sprachgrammatik enthält nicht die Schlüsselwörter "öffentlich", "privat" oder "geschützt". Dies würde bedeuten, dass alles öffentlich ist. Natürlich könnte es eine alternative Methode geben, um Zugriffsmodifikatoren ohne diese Schlüsselwörter anzugeben, aber ich konnte sie nicht in der Sprachreferenz finden.

Scroog1
quelle
0

Hoffentlich etwas Zeit für diejenigen sparen, die etwas Ähnliches wie geschützte Methoden wollen:

Wie aus anderen Antworten hervorgeht, stellt swift jetzt den Modifikator "privat" bereit, der eher datei- als klassenbezogen definiert ist, wie beispielsweise in Java oder C #. Dies bedeutet, dass Sie geschützte Methoden mit schnellen privaten Methoden ausführen können, wenn sie sich in derselben Datei befinden

  1. Erstellen Sie eine Basisklasse für 'geschützte' Methoden (tatsächlich privat).
  2. Unterklassen Sie diese Klasse, um dieselben Methoden zu verwenden
  3. In anderen Dateien können Sie auch dann nicht auf die Basisklassenmethoden zugreifen, wenn Sie eine Unterklasse verwenden

zB Datei 1:

class BaseClass {
    private func protectedMethod() {

    }
}

class SubClass : BaseClass {
    func publicMethod() {
        self.protectedMethod()  //this is ok as they are in same file
    }
}

Datei 2:

func test() {
    var a = BaseClass()
    a.protectedMethod() //ERROR


    var b = SubClass()
    b.protectedMethod() //ERROR
}

class SubClass2 : BaseClass {
    func publicMethod() {
        self.protectedMethod() //ERROR
    }

}}

james_alvarez
quelle
-2

Bis Swift 2.0 gab es nur drei Zugriffsebenen [Öffentlich, intern, privat], aber in Swift 3.0 hat Apple zwei neue Zugriffsebenen hinzugefügt, nämlich [Öffnen, Dateityp]. In Swift 3.0 gibt es jetzt 5 Zugriffsebenen. Hier möchte ich die Rolle löschen von diesen beiden Zugriffsebenen 1. Offen: Dies ist der öffentlichen sehr ähnlich, aber der einzige Unterschied besteht darin, dass die Öffentlichkeit auf die Unterklasse zugreifen und diese überschreiben kann. Die offene Zugriffsebene kann nicht darauf zugreifen, dass dieses Bild von der Medium-Website stammt, und dies beschreibt den Unterschied zwischen offenem und öffentlichem Zugang

Jetzt zur zweiten neuen Zugriffsebene 2. Der Dateityp ist eine größere Version der privaten oder weniger Zugriffsebene als die interne. Der Dateityp kann auf den erweiterten Teil der [Klasse, Struktur, Aufzählung] zugreifen, und private kann nicht auf den erweiterten Teil des Codes zugreifen, auf den nur zugegriffen werden kann Der lexikalische Umfang dieses Bildes stammt von der Medium-Website und beschreibt den Unterschied zwischen Dateityp und privater Zugriffsebene

Dilip Tilonia
quelle