willSet و didSet ناظران ویژگی (property observers) در Swift هستند که به شما امکان میدهند قبل و بعد از تغییر مقدار ویژگی کد اجرا کنید. برخلاف computed properties، ناظران مقدار جدیدی محاسبه نمیکنند، فقط به تغییر واکنش نشان میدهند. طبق مستندات Apple، The Swift Programming Language (2026)، ناظران برای اعتبارسنجی دادهها، همگامسازی رابط و ثبت تغییرات در کد ضروری هستند.
نکات اصلی
willSet و didSet property observers (ناظران ویژگی) در Swift هستند، یک مکانیزم داخلی برای ردیابی تغییرات stored properties.
برخلاف زبانهای دیگر که نیاز به پیادهسازی دستی setters یا سیستمهای callback دارند، Swift یک syntax اعلانی برای واکنش به تغییرات ارائه میدهد. ناظران مستقیماً پس از اعلان ویژگی اضافه میشوند و نیازی به فراخوانی جداگانه ندارند.
طبق Apple Developer Documentation (2026)، property observers برای stored properties هر کلاس، ساختار یا شمارش پشتیبانی میشوند. آنها با computed properties کار نمیکنند، زیرا آنها مقداری را ذخیره نمیکنند — برای آنها واکنش به تغییر مستقیماً در setter پیادهسازی میشود.
willSet بلافاصله قبل از تخصیص مقدار جدید به ویژگی فراخوانی میشود. در داخل willSet پارامتر ضمنی newValue در دسترس است که مقدار تعیینشده را شامل میشود. در این لحظه مقدار فعلی ویژگی هنوز تغییر نکرده است — میتوانید مقدار قدیمی را مستقیماً از طریق ویژگی بخوانید.
طبق Swift Evolution proposal SE-0001 (2024)، willSet امکان انجام اعتبارسنجی یا ثبت رویداد قبل از تغییر واقعی را فراهم میکند. اگر در willSet یک استثنا پرتاب شود — مقدار جدید اعمال نخواهد شد، که ناظران را به یک مکانیزم حفاظت از داده تبدیل میکند.
didSet بلافاصله پس از تخصیص مقدار جدید فراخوانی میشود. در داخل didSet پارامتر ضمنی oldValue در دسترس است که مقدار قبل از تغییر را شامل میشود. در این لحظه ویژگی قبلاً مقدار جدید را دارد و میتوانید آن را با مقدار قدیمی مقایسه کنید.
طبق Swift by Sundell (2025)، didSet محبوبترین ناظر است، زیرا اغلب برای پردازش پس از تغییر مورد نیاز است: بهروزرسانی UI، محاسبه مجدد فیلدهای وابسته یا ارسال داده به سرور پس از تغییر.
Property observers بلافاصله پس از ویژگی با استفاده از آکولاد اعلان میشوند. حداقل syntax فقط به یک ناظر نیاز دارد، اما میتوان هر دو را اعلان کرد.
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)، این رفتار با بسیاری از زبانهای دیگر که در آنها setters حتی در سازندهها فراخوانی میشوند متفاوت است. 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 امکان برگرداندن یا تصحیح مقدار نامعتبر را بلافاصله پس از تنظیم آن فراهم میکند. این کار جایگزین setters حجیم در Objective-C میشود و یکپارچگی داده را در سطح مدل تضمین میکند.
var age: Int = 0 {
didSet {
if age < 0 || age > 150 {
age = oldValue
}
}
}
هنگام تغییر ویژگی مرتبط، میتوان بدون فراخوانی جداگانه متد بهروزرسانی، المانهای رابط را بهطور خودکار بهروزرسانی کرد.
var userName: String = "" {
didSet {
nameLabel.text = userName
}
}
willSet برای ثبت رویداد به منظور debugging یا حسابرسی مناسب است. میتوانید زمان و مقدار جدید را قبل از اعمال آن ثبت کنید و اطمینان حاصل کنید که log حاوی دادههای اصلی برای تحلیل است.
طبق 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 به تغییر مقدار موجود واکنش نشان میدهد. انتخاب بین آنها توسط semantics تعیین میشود — اگر ویژگی مشتق از دادههای دیگر است، از 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 است که قبل از تغییر مقدار اجرا میشود. Setter در computed property روشی برای محاسبه مقدار جدید است، نه مشاهده مقدار موجود.
فراخوانی مجدد didSet باعث بازگشت میشود. بدون شرط خروج، این منجر به سرریز پشته و خاتمه اضطراری برنامه میشود.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید