willSet och didSet är egenskapsobservatörer (property observers) i Swift som gör det möjligt att utföra kod före och efter ändring av ett egenskapsvärde. Till skillnad från computed properties beräknar observatörer inte ett nytt värde, de reagerar bara på förändringen. Enligt Apples dokumentation, The Swift Programming Language (2026), är observatörer oumbärliga vid datavalidering, gränssnittssynkronisering och loggning av kodändringar.
Huvudpunkter
willSet och didSet är property observers (egenskapsobservatörer) i Swift, en inbyggd mekanism för att spåra ändringar av stored properties.
Till skillnad från andra språk där manuell implementering av setters eller callback-system krävs, tillhandahåller Swift en deklarativ syntax för att reagera på förändringar. Observatörer läggs till direkt efter egenskapsdeklarationen och kräver inget separat anrop.
Enligt Apple Developer Documentation (2026) stöds property observers för stored properties av alla klasser, strukturer eller uppräkningar. De fungerar inte med computed properties eftersom dessa inte lagrar något värde — för dem implementeras reaktionen på förändring direkt i settern.
willSet anropas omedelbart före tilldelning av det nya värdet till egenskapen. Inuti willSet finns den implicita parametern newValue tillgänglig, som innehåller värdet som kommer att ställas in. I detta ögonblick har egenskapens nuvarande värde ännu inte ändrats — du kan läsa det gamla värdet direkt via egenskapen.
Enligt Swift Evolution proposal SE-0001 (2024) ger willSet möjlighet att utföra validering eller loggning före den faktiska ändringen. Om ett undantag kastas i willSet — kommer det nya värdet inte att tillämpas, vilket gör observatörer till en dataskyddsmekanism.
didSet anropas omedelbart efter tilldelning av det nya värdet. Inuti didSet finns den implicita parametern oldValue tillgänglig, som innehåller värdet före ändringen. I detta ögonblick innehåller egenskapen redan det nya värdet och du kan jämföra det med det gamla.
Enligt Swift by Sundell (2025) är didSet den populäraste observatören eftersom den oftast behövs för efterbehandling: UI-uppdatering, omberäkning av beroende fält eller sändning av data till servern efter en ändring.
Property observers deklareras omedelbart efter egenskapen med hjälp av klammerparenteser. Minimal syntax kräver bara en observatör, men båda kan deklareras.
var score: Int = 0 {
willSet {
print("Poängen kommer att ändras till \(newValue)")
}
didSet {
print("Poängen ändrades från \(oldValue) till \(score)")
}
}
Båda observatörerna är valfria — du kan ange bara willSet eller bara didSet. För willSet kan newValue döpas om genom att ange namnet inom parentes.
var username: String = "guest" {
willSet(newName) {
print("Håller på att ställa in \(newName)")
}
didSet(oldName) {
print("Var \(oldName), nu \(username)")
}
}
Enligt Swift Language Guide (2026) förbättrar omdöpning av parametrar kodens läsbarhet, särskilt när egenskapen och observatörerna används i ett stort projekt med långa namn.
Ordningen för utförande är strikt bestämd: först willSet (gamla värdet är tillgängligt), sedan tilldelning, därefter didSet (nya värdet är tillgängligt).
class Temperature {
var celsius: Double = 0.0 {
willSet {
print("Temperaturen kommer att ändras från \(celsius) till \(newValue)")
}
didSet {
if celsius > 100.0 {
print("Kokpunkten överskreds!")
}
}
}
}
Viktig begränsning: observatörer anropas inte vid initiering av egenskapen under skapandet av en instans. Inuti init utlöser inte värdetilldelning willSet och didSet — detta förhindrar oönskade bieffekter i konstruktionsfasen.
Enligt Apple Swift Blog (2025) skiljer sig detta beteende från många andra språk där setters anropas även i konstruktorer. Swift väljer säkerhet: observatörer börjar fungera först efter slutförd objektinitiering.
Ändring av egenskap inuti didSet kan leda till upprepade anrop av observatörer. Swift blockerar inte rekursion — programmeraren måste kontrollera den själv.
var counter: Int = 0 {
didSet {
if counter < 5 {
counter += 1
}
}
}
En sådan kod kommer att skapa total rekursion med stack overflow om inget utträdesvillkor finns. Enligt Stack Overflow Swift Community (2025) är detta ett av de vanligaste misstagen hos nybörjare vid arbete med property observers.
Strukturer stöder willSet och didSet för stored properties utan begränsningar. Det är viktigt att komma ihåg att strukturer är värdetyper (value types) och att modifiering av egenskap inuti en muterande metod också utlöser observatörer.
struct Point {
var x: Double = 0.0 {
didSet {
print("X ändrades till \(x)")
}
}
var y: Double = 0.0 {
didSet {
print("Y ändrades till \(y)")
}
}
}
var point = Point()
point.x = 5.0
Egenskapsobservatörer används i Swift-projekt för en bred spektrum av uppgifter: från UI-synkronisering till datavalidering och loggning.
didSet gör det möjligt att ångra eller korrigera ett ogiltigt värde omedelbart efter att det har ställts in. Detta ersätter omfattande setters i Objective-C och säkerställer dataintegritet på modellnivå.
var age: Int = 0 {
didSet {
if age < 0 || age > 150 {
age = oldValue
}
}
}
Vid ändring av en relaterad egenskap kan gränssnittselement uppdateras automatiskt utan separat anrop av en uppdateringsmetod.
var userName: String = "" {
didSet {
nameLabel.text = userName
}
}
willSet är praktiskt för loggning i felsöknings- eller revisionssyfte. Du kan registrera tiden och det nya värdet före tillämpning, vilket garanterar att loggen innehåller originaldata för analys.
Enligt objc.io (2025) är property observers särskilt användbara i arkitekturer med enkelriktat dataflöde, där varje egenskapsändring registreras för senare återskapning av tillståndet.
Computed properties beräknar värdet direkt och har ingen lagring, medan willSet och didSet arbetar på en stored property med ett faktiskt värde.
| Egenskap | Property Observers | Computed Properties |
|---|---|---|
| Lagrar värde | Ja | Nej |
| Utför kod vid ändring | Ja | Nej |
| Typ av deklaration | var | var (get/set) |
| Åtkomstparametrar | newValue, oldValue | newValue (i set) |
| Initiering | Kräver startvärde | Krävs inte |
Den viktigaste skillnaden: computed property beräknar värdet vid varje åtkomst, medan property observer reagerar på förändring av ett befintligt värde. Valet mellan dem dikteras av semantik — om egenskapen är härledd från andra data, använd computed; om det är ett oberoende värde vars förändringar måste observeras, använd willSet/didSet.
Det vanligaste misstaget — rekursivt anrop av didSet utan utträdesvillkor. Varje ändring av egenskapen inuti didSet utlöser observer igen, vilket leder till en oändlig loop.
Det näst vanligaste misstaget — försök att använda observatörer på let-egenskaper. Swift-kompilatorn ger ett fel eftersom let är en konstant.
Det tredje misstaget — att ignorera att observatören inte anropas vid initiering. Utvecklare som förväntar sig att willSet aktiveras inuti init får oväntat beteende.
Det fjärde problemet — tillämpning av observatörer på egenskaper i extension. Swift förbjuder att lägga till willSet/didSet till stored properties i extension.
Enligt Ray Wenderlich (2025) hjälper förståelsen av dessa begränsningar att undvika buggar i tidiga skeden och gör Swift-koden mer förutsägbar.
Vanliga frågor
Ja, varje observatör är valfri. Du kan deklarera bara willSet, bara didSet eller båda samtidigt.
Nej, Swift förbjuder att lägga till willSet och didSet i extension för stored properties. Observatörer deklareras endast i den ursprungliga typdefinitionen.
Nej, vid initiering anropas inte observatörer. Detta är en skyddsmekanism som förhindrar bieffekter i objektets konstruktionsfas.
willSet är en observatör av stored property som utförs före värdändringen. En setter i computed property är ett sätt att beräkna ett nytt värde, inte att observera ett befintligt.
Upprepat anrop av didSet orsakar rekursion. Utan utträdesvillkor leder detta till stack overflow och programmet avslutas oväntat.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också