---
title: "القيمتان القديمة والجديدة في willSet وdidSet"
description: "تتيح willSet وdidSet الوصول إلى القيمتين الجديدة والقديمة بأسماء جاهزة. تعرّف إلى وقت تشغيلهما، وما يحدث أثناء التهيئة وعند إعادة إسناد القيمة نفسها."
author: "Omar Albeik"
date: 2019-12-06
type: note
topics: [swift, software, engineering]
language: ar
reading_time_minutes: 2
canonical_url: https://omaralbeik.com/ar/blog/property-observers-old-and-new-value
translation_url: https://omaralbeik.com/en/blog/property-observers-old-and-new-value
source_url: https://omaralbeik.com/ar/blog/property-observers-old-and-new-value.md
---

# القيمتان القديمة والجديدة في willSet وdidSet

تتيح Swift الوصول إلى القيمة الجديدة داخل `willSet` باسم `newValue`، وإلى
القيمة السابقة داخل `didSet` باسم `oldValue`. لا تحتاج إلى تعريف هذين الاسمين
بنفسك:

```swift
var language = "ObjC" {
  willSet {
    print("about to replace \(language) with \(newValue)")
  }
  didSet {
    print("replaced \(oldValue) with \(language)")
  }
}
```

داخل `willSet`، ما زالت الخاصية تحمل قيمتها القديمة، وتأتي القيمة الجديدة من
الوسيط. داخل `didSet`، تحمل الخاصية قيمتها الجديدة، ويحتفظ `oldValue` بالقيمة
السابقة.

كتابة `willSet(newValue)` أو `didSet(oldValue)` تعيد تسمية الوسيط باسمه
الافتراضي، فلا حاجة إليها. استخدم اسمًا صريحًا عندما يوضح المعنى، مثل:

```swift
didSet(previousUser) {
  guard previousUser.id != user.id else { return }
  reload()
}
```

الأهم من أسماء الوسائط هو توقيت تشغيل المراقبين. هذه ثلاث حالات تستحق
الانتباه.

## لا تعمل أثناء التهيئة

عند تهيئة الخاصية مباشرة داخل `init`، لا تُستدعى مراقباتها. ينطبق ذلك أيضًا
على التهيئة التلقائية لحقول البنية (memberwise initializer). إذا كان لديك
إعداد يجب أن يعمل مع القيمة الأولى، فاستدعه صراحة في نهاية التهيئة بدل
الاعتماد على `didSet`.

## لا تعمل عند الإسناد من داخل `didSet`

يمكنك تعديل قيمة الخاصية داخل `didSet` الخاص بها دون استدعائه من جديد. يسمح
ذلك، مثلًا، بحصر القيمة بين حدين، ويمنع تكرار الاستدعاء إلى ما لا نهاية. لكن
لا تعتمد على هذا التعديل لتشغيل `didSet` مرة ثانية.

## تعمل مع كل كتابة، لا مع كل تغيير

يعمل المراقبان حتى عند إسناد القيمة نفسها. إذا كان `didSet` يعيد تحميل
الواجهة، فتحقق أولًا من أن القيمة تغيرت:

```swift
didSet {
  guard oldValue != items else { return }
  tableView.reloadData()
}
```

وإذا كانت الخاصية من نوع `struct`، فتعديل أحد حقولها يُعد كتابة إلى الخاصية
نفسها. مثلًا، يشغّل `settings.fontSize = 14` مراقب `didSet` على `settings`. ضع
ذلك في الحسبان قبل تنفيذ عمل مكلف داخل المراقب.

هل واجهت سلوكًا غير متوقع في مراقبات الخصائص؟ [احكِ لي ما حدث](/ar/contact)،
وما إذا غيّر طريقتك في استخدام `didSet`. وقد تفيد هذه الملاحظة زميلًا يحاول
فهم سبب إعادة تحميل الواجهة دون حاجة.
