2016-01-07 17 views
24

Właśnie zauważyłem, że static członkowie Swift structs są domyślnie lazy.Niejawne leniwe statyczne elementy w Swift

Na przykład, to zadzwoni tylko init raz:

class Baz { 
    init(){ 
     print("initializing a Baz") 
    } 
} 
struct Foo { 
    static let bar = Baz() 
} 

var z = Foo.bar 
z = Foo.bar 

Jakie jest uzasadnienie tego?

Co jeśli chcę przeciwnego zachowania?

+5

Istnieje kilka powodów, dla których zmienne globalne są leniwe tutaj: https://developer.apple.com/swift/blog/?id=7. Członkowie statyczni prawdopodobnie mieliby podobne uzasadnienie, z wyjątkiem jeszcze mniejszej przyczyny inicjalizacji podczas uruchamiania (to znaczy, co jeśli nigdy nie używałeś nawet typu, został on po prostu zaimportowany przez import? Gdyby wszystkie statyczne zmienne zostały zainicjalizowane niezależnie od użycia ?) –

Odpowiedz

39

Właściwość static definiuje "właściwość typu", taką, która jest tworzona tylko raz i raz. Jak zauważasz, dzieje się to leniwie, ponieważ statyka zachowuje się jak globale. I jak The Swift Programming Language: Properties mówi:

stałe i zmienne globalne są zawsze obliczane leniwie, w sposób podobny do Lazy Stored Properties. W przeciwieństwie do leniwych przechowywanych właściwości, globalne stałe i zmienne nie muszą być oznaczone modyfikatorem lazy.

To niejawnie leniwy zachowanie jest dlatego, ponieważ Swift Blog: Files and Initialization mówi:

pozwala niestandardowe inicjalizatory, czas uruchamiania w Swift Wagi czysto bez globalnych inicjalizatorów aby go spowolnić, a kolejność wykonywania jest całkowicie przewidywalne.

Świadomie zaprojektowali go w ten sposób, aby uniknąć niepotrzebnego opóźniania uruchomienia aplikacji.

Jeśli chcesz utworzyć instancję właściwości static w określonym miejscu w aplikacji (zamiast odkładać ją tam, gdzie była używana po raz pierwszy), po prostu odwołaj się do tej właściwości static w tym wcześniejszym punkcie, a obiekt zostanie zainicjowany w tym czasie. Biorąc pod uwagę wysiłki, jakie włożyliśmy w zmniejszenie opóźnień w uruchamianiu naszych aplikacji, zazwyczaj nie chcemy tego synchronicznie podczas pierwszego uruchomienia aplikacji, ale można to zrobić w dowolnym miejscu.

+0

W przykładzie "static let cache = NSCache()", pamięć podręczna została zainicjalizowana w czasie rozruchu, lub tylko, gdy "najpierw używana jest pamięć podręczna" ...? – Fattie

+0

Jest leniwy. Zaktualizowałem swoją odpowiedź, aby wyjaśnić tę kwestię. – Rob

Powiązane problemy