willSet и didSet са наблюдатели на свойства (property observers) в Swift, които позволяват изпълнение на код преди и след промяна на стойността на свойство. За разлика от computed properties, наблюдателите не изчисляват нова стойност, а само реагират на промяната. Според документацията на Apple, The Swift Programming Language (2026), наблюдателите са незаменими при валидация на данни, синхронизация на интерфейс и регистриране на промени в кода.
Основни точки
willSet и didSet са property observers (наблюдатели на свойства) в Swift, вграден механизъм за проследяване на промени на stored properties.
За разлика от други езици, където се изисква ръчна имплементация на сетъри или callback системи, Swift предоставя декларативен синтаксис за реакция на промени. Наблюдателите се добавят непосредствено след декларацията на свойството и не изискват отделно извикване.
Според Apple Developer Documentation (2026), property observers се поддържат за stored properties на всеки клас, структура или изброяване. Те не работят с computed properties, тъй като те не съхраняват стойност — за тях реакцията на промяна се имплементира директно в сетъра.
willSet се извиква непосредствено преди присвояване на новата стойност на свойството. Вътре в willSet е достъпен имплицитният параметър newValue, съдържащ стойността, която ще бъде зададена. В този момент текущата стойност на свойството все още не се е променила — можете да прочетете старата стойност директно чрез свойството.
Според Swift Evolution proposal SE-0001 (2024), willSet предоставя възможност за извършване на валидация или регистриране преди действителната промяна. Ако в willSet бъде хвърлено изключение — новата стойност няма да се приложи, което прави наблюдателите механизъм за защита на данните.
didSet се извиква непосредствено след присвояване на новата стойност. Вътре в didSet е достъпен имплицитният параметър oldValue, съдържащ стойността преди промяната. В този момент свойството вече съдържа новата стойност и можете да я сравните със старата.
Според Swift by Sundell (2025), didSet е най-популярният наблюдател, тъй като най-често е необходим за последваща обработка: обновяване на UI, преизчисляване на зависими полета или изпращане на данни към сървъра след промяна.
Property observers се декларират непосредствено след свойството с помощта на фигурни скоби. Минималният синтаксис изисква само един наблюдател, но могат да бъдат декларирани и двата.
var score: Int = 0 {
willSet {
print("Резултатът ще се промени на \(newValue)")
}
didSet {
print("Резултатът се промени от \(oldValue) на \(score)")
}
}
И двата наблюдателя са незадължителни — можете да посочите само willSet или само didSet. За willSet, newValue може да бъде преименуван чрез посочване на името в скоби.
var username: String = "guest" {
willSet(newName) {
print("Ще задам \(newName)")
}
didSet(oldName) {
print("Беше \(oldName), сега \(username)")
}
}
Според Swift Language Guide (2026), преименуването на параметри подобрява четимостта на кода, особено когато свойството и наблюдателите се използват в голям проект с дълги имена.
Редът на изпълнение е строго определен: първо willSet (старата стойност е достъпна), след това присвояване, после didSet (новата стойност е достъпна).
class Temperature {
var celsius: Double = 0.0 {
willSet {
print("Температурата ще се промени от \(celsius) на \(newValue)")
}
didSet {
if celsius > 100.0 {
print("Точката на кипене е превишена!")
}
}
}
}
Важно ограничение: наблюдателите не се извикват при инициализация на свойството в процеса на създаване на инстанция. Вътре в init, присвояването на стойност не задейства willSet и didSet — това предотвратява нежелани странични ефекти на етапа на конструиране.
Според Apple Swift Blog (2025), това поведение се различава от много други езици, където сетърите се извикват дори в конструкторите. Swift избира безопасността: наблюдателите започват да работят едва след завършване на инициализацията на обекта.
Промяна на свойство вътре в didSet може да доведе до повторно извикване на наблюдателите. Swift не блокира рекурсията — програмистът трябва да я контролира сам.
var counter: Int = 0 {
didSet {
if counter < 5 {
counter += 1
}
}
}
Такъв код ще създаде тотална рекурсия с препълване на стека, ако не е предвидено условие за изход. Според Stack Overflow Swift Community (2025), това е една от най-честите грешки на начинаещи програмисти при работа с property observers.
Структурите поддържат willSet и didSet за stored properties без ограничения. Важно е да запомните, че структурите са value types и модификацията на свойство вътре в мутиращ метод също задейства наблюдателите.
struct Point {
var x: Double = 0.0 {
didSet {
print("X се промени на \(x)")
}
}
var y: Double = 0.0 {
didSet {
print("Y се промени на \(y)")
}
}
}
var point = Point()
point.x = 5.0
Наблюдателите на свойства се използват в Swift проекти за широк спектър от задачи: от UI синхронизация до валидация на данни и регистриране.
didSet позволява отмяна или коригиране на невалидна стойност веднага след задаването ѝ. Това замества обемистите сетъри в Objective-C и осигурява цялост на данните на ниво модел.
var age: Int = 0 {
didSet {
if age < 0 || age > 150 {
age = oldValue
}
}
}
При промяна на свързано свойство можете автоматично да обновявате елементите на интерфейса без отделно извикване на метод за обновяване.
var userName: String = "" {
didSet {
nameLabel.text = userName
}
}
willSet е удобен за регистриране с цел отстраняване на грешки или одит. Можете да запишете времето и новата стойност преди прилагането ѝ, гарантирайки, че логът съдържа оригиналните данни за анализ.
Според objc.io (2025), property observers са особено полезни в архитектури с еднопосочен поток от данни, където всяка промяна на свойство се записва за последващо възпроизвеждане на състоянието.
Computed properties изчисляват стойността в движение и нямат хранилище, докато willSet и didSet работят върху stored property с действителна стойност.
| Характеристика | Property Observers | Computed Properties |
|---|---|---|
| Съхранява стойност | Да | Не |
| Изпълнява код при промяна | Да | Не |
| Тип декларация | var | var (get/set) |
| Параметри за достъп | newValue, oldValue | newValue (в set) |
| Инициализация | Изисква начална стойност | Не се изисква |
Ключовата разлика: computed property изчислява стойността при всяко обръщение, а property observer реагира на промяна на съществуваща стойност. Изборът между тях се диктува от семантиката — ако свойството е производно на други данни, използвайте computed; ако е независима стойност, чиито промени трябва да се наблюдават, използвайте willSet/didSet.
Най-честата грешка — рекурсивно извикване на didSet без условие за изход. Всяка промяна на свойство вътре в didSet задейства отново observer, което води до безкраен цикъл.
Втората често срещана грешка — опит за използване на наблюдатели върху let свойства. Компилаторът на Swift ще даде грешка, тъй като let е константа.
Третата грешка — игнориране на факта, че observer не се извиква при инициализация. Разработчици, които очакват задействане на willSet вътре в init, получават неочаквано поведение.
Четвъртият проблем — прилагане на наблюдатели към свойства в extension. Swift забранява добавянето на willSet/didSet към stored properties в extension.
Според Ray Wenderlich (2025), разбирането на тези ограничения помага да се избегнат грешки в ранните етапи и прави кода на Swift по-предвидим.
Често задавани въпроси
Да, всеки наблюдател е незадължителен. Можете да декларирате само willSet, само didSet или и двата наведнъж.
Не, Swift забранява добавянето на willSet и didSet в extension за stored properties. Наблюдателите се декларират само в оригиналната дефиниция на типа.
Не, при инициализация наблюдателите не се извикват. Това е защитен механизъм, предотвратяващ странични ефекти на етапа на конструиране на обекта.
willSet е наблюдател на stored property, който се изпълнява преди промяна на стойността. Сетърът в computed property е начин за изчисляване на нова стойност, а не за наблюдение на съществуваща.
Повторно извикване на didSet ще предизвика рекурсия. Без условие за изход това ще доведе до препълване на стека и аварийно прекратяване на програмата.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също