Static en class properties zijn eigenschappen die aan het type toebehoren in plaats van aan een instantie. Historisch zijn ze ontstaan om informatie op te slaan die gemeenschappelijk is voor alle instanties (bijvoorbeeld tellers, configuraties, fabrieken). In Swift kan static worden gebruikt in alle typen (class, struct, enum), terwijl class alleen in klassen kan worden gebruikt en alleen voor berekende eigenschappen, wat de mogelijkheid biedt tot overschrijven in afgeleiden klassen.
Probleem: Onjuist gebruik van statische eigenschappen kan leiden tot race-voorwaarden en fouten bij toegang vanuit verschillende threads. Het is ook gemakkelijk om static en class te verwarren en het verkeerde mechanisme te kiezen voor overschrijving in afgeleiden klassen.
Oplossing:
Voorbeeld code:
class Counter { static var count = 0 static let queue = DispatchQueue(label: "counter.queue") static func increment() { queue.sync { count += 1 } } class var typeDescription: String { return "Generic Counter" } } class NamedCounter: Counter { override class var typeDescription: String { return "Named Counter" } }
Belangrijkste kenmerken:
Vraag 1: Kan je een static let property declareren als een berekend (computed) eigenschap met get?
Ja, een static property kan zowel stored als computed zijn. Voor let eigenschappen is dit meestal een constante, maar een static var kan heel goed berekend zijn:
struct Math { static var pi: Double { return 3.1415926 } }
Vraag 2: Zijn static var thread-safe per standaard?
Nee, als static var wordt gewijzigd vanuit verschillende threads, kunnen er race-voorwaarden optreden. read/write moet handmatig worden gesynchroniseerd.
Vraag 3: Kan je class var gebruiken voor stored eigenschappen?
Nee, class var moet altijd een berekende eigenschap zijn (property with get/optional set), stored eigenschappen zijn alleen toegestaan voor static.
In de applicatie werd de inlog teller van de gebruiker opgeslagen in static var en werd deze geïnkremmenteerd vanuit verschillende threads zonder synchronisatie.
Voordelen:
Nadelen:
Voor een globaal configuratie object werd static let gebruikt en was de toegang er alleen om te lezen of met gebruik van DispatchQueue voor schrijven.
Voordelen:
Nadelen: