Xcode-Spielplätze können nicht auf schnelle Dateien im Ordner "Quellen" zugreifen

73

Ich habe gerade ein Upgrade auf Xcode 6.3 durchgeführt und sie haben den Spielplätzen etwas Neues angeboten. Wenn Sie neue Spielplätze erstellen und den Projektnavigator öffnen, wird ein Quellenordner angezeigt, in dem sich eine Datei "SupportCode.swift" befindet. Am Anfang dieser Datei steht

Diese Datei (und alle anderen Swift-Quelldateien im Quellenverzeichnis dieses Spielplatzes) werden in ein Framework vorkompiliert, das .playground automatisch zur Verfügung gestellt wird.

Ich habe versucht, dort eine Funktion einzurichten, die meinem Spielplatz nicht zur Verfügung steht. Was mache ich falsch? Muss ich die Datei SupportCode.swift manuell kompilieren? Wie?

DerrickHo328
quelle

Antworten:

196

Sie müssen Ihren Klassen, Methoden und Eigenschaften im Quellordner ein öffentliches Zugriffsattribut hinzufügen , um sie über die Hauptspielplatzdatei zugänglich zu machen, da sie vom Compiler als separates Modul behandelt werden

Vitali
quelle
22
Ich finde es wirklich seltsam, dass ich eine Klasse öffentlich machen UND ihre Init-Funktion öffentlich machen muss.
DerrickHo328
12
wäre toll wenn wir so etwas wie @testable importfür
spielplätze bekommen würden
3
@ Calimari328 Wenn Sie Ihre Klasse als öffentlich deklarieren, wird sie außerhalb sichtbar, aber wenn Sie init () als öffentlich deklarieren, müssen Sie Instanzen von außen instanziieren (erstellen). Wenn Sie also einen Zugriff auf die Klasse gewähren möchten, aber gleichzeitig die Instanziierung einschränken möchten, deklarieren Sie init () als weniger sichtbar. Ich gab ein Beispiel mit Singleton-Implementierung - um es klarer zu machen
Nikita Kurtin
19

Spielplätze eignen sich gut für Tests. Legen Sie Ihren gesamten Code in das SourcesVerzeichnis und haben Sie für jeden Test eine öffentlich zugängliche 'Test'-Klasse. Führen Sie dann die öffentlich zugänglichen Tests vom Spielplatz aus durch.

playground

Test1.run()
Testx.run()
...

Sources/Test1.swift

public class Test1 {      
  public static func run() {
    let my_class = MyClass()
    let result = my_class.do_something()
    print(result)
  }
}

Sources/MyClass.swift

class MyClass {
  func do_something() -> String {
    return "lol"
  }
}
nich
quelle
Warum benötigen Sie die Test1-Klasse und die statische 'run'-Methode? Warum nicht einfach eine öffentliche globale test1 () -Funktion erstellen? Erreicht das Gleiche, wenn die Klasse nichts hinzufügt.
Mark A. Donohoe
9

Wie bereits erwähnt, stehen beim Erstellen von .swift-Dateien im Quellordner diese automatisch Ihrem Spielplatzcode zur Verfügung. Um den Zugriff auf verschiedene Teile dieser Datei zu steuern, können Sie Modifikatoren für die Zugriffsebene verwenden, die : public, internal& private.

Laut Swift Programmiersprache Zugriffskontrolle

Die Standardzugriffsebene ist in den meisten Fällen internaldiejenige, auf die innerhalb des Moduls zugegriffen werden kann, nicht jedoch außerhalb.

Mit anderen Worten, wenn Sie eine Klasse ohne Zugriffsmodifikator deklarieren, können Sie von einer anderen Datei im Quellordner darauf zugreifen, jedoch NICHT in der Hauptdatei Ihres Spielplatzes. Wenn Sie dagegen eine Klasse mit dem Modifikator public deklarieren, können Sie in beiden Fällen darauf zugreifen.

für den praktischen Gebrauch: Lassen Sie uns eine Singleton-Implementierung durchführen. Zuerst: Ich erstelle eine neue Datei im Quellordner mit dem Namen 'Singy.swift' mit folgendem Code:

public class Singy {
    public var name = ""
    private static var instance: Singy?
    private init() {}

    public static func getSingy() -> Singy {
        if Singy.instance == nil {
            Singy.instance = Singy()
        }
        return Singy.instance!
    }
}

Zweitens: von meinem Spielplatz

var s1 = Singy.getSingy()
var s2 = Singy.getSingy()
s1.name = "One"
print(s2.name)

Beide s1und s2verweisen auf dieselbe Instanz, die jedoch nur innerhalb der Klasse erstellt wurde

Nikita Kurtin
quelle