مراقبو الخصائص
جزء من قسم البرمجة كائنية التوجه في رحلة Swift على Coddy. الدرس 13 من 57.
ينفّذ مراقب الخاصية تعليمات برمجية كلما تغيّرت خاصية مخزّنة. يُنفّذ didSet مباشرةً بعد تخزين القيمة الجديدة، وداخله يحتوي oldValue على القيمة السابقة:
class Player {
var score = 0 {
didSet {
print("score \(oldValue) -> \(score)")
}
}
}
let p = Player()
p.score = 10
p.score += 5الناتج:
score 0 -> 10
score 10 -> 15يتم تشغيل willSet قبل التغيير، مع القيمة الواردة باعتبارها newValue. لا يتم تشغيل المراقبين عندما تحصل الخاصية على قيمتها الأولية:
struct Thermostat {
var target = 20 {
willSet { print("changing to \(newValue)") }
didSet { print("changed from \(oldValue)") }
}
}
var t = Thermostat()
t.target = 22الناتج:
changing to 22
changed from 20didSet مكان مناسب للحفاظ على صلاحية قيمة. لا يؤدي الإسناد إلى الخاصية داخل didSet الخاص بها إلى تشغيل المراقب مرة أخرى:
struct Volume {
var level = 5 {
didSet {
if level > 10 { level = 10 }
if level < 0 { level = 0 }
}
}
}
var v = Volume()
v.level = 42
print(v.level)
v.level = -3
print(v.level)الناتج:
10
0يمكن للمراقبات أيضًا الاحتفاظ بسجلّ أو تحديث حالة مرتبطة، مما يُبقي هذا المنطق بجوار الخاصية بدلًا من تشتيته في أنحاء الشيفرة:
class Account {
var history: [Int] = []
var balance = 0 {
didSet { history.append(balance - oldValue) }
}
}
let a = Account()
a.balance = 100
a.balance = 70
print(a.history)الناتج:
[100, -30]التحدي
سهلأكمل الصنف Tank. يجب أن تبقى الخاصية المخزنة level بين 0 وcapacity: أضف didSet لتصحيح القيم الواقعة خارج هذا النطاق، ولإلحاق تحذير low بـalerts كلما انتهى المستوى المصحح تحت 20% من السعة (وكان المستوى السابق غير منخفض).
يقرأ الكود المزوَّد السعة ثم يطبّق التغيير +n أو -n. ويطبع المستوى بعد كل تغيير، وأخيرًا alerts: مع عدد التحذيرات.
ضع كودك في Tank.swift. يحتوي main.swift على كود الإدخال/الإخراج المزوَّد، ولا يمكن تعديله.
جرّب بنفسك
// كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
var input: [String] = []
while let line = readLine() { input.append(line) }
let tank = Tank(capacity: Int(input[0])!)
for cmd in input.dropFirst() {
let n = Int(cmd.dropFirst())!
tank.level += cmd.hasPrefix("+") ? n : -n
print(tank.level)
}
print("alerts: \(tank.alerts.count)")
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الأصناف والكائنات
العمل مع الملفاتتعريف الأصنافالأساليب وselfالمُهيِّئاتالأصناف هي مراجعمراجعة - بطاقة المكتبة4التغليف
التحكم في الوصولللقراءة فقط من الخارجحماية الحالةالمهيئات القابلة للفشلمراجعة - الحساب البنكي7تعدد الأشكال والأنواع العامة
تعدد الأشكالتحويل الأنواعالدوال العامةالأنواع العامةمراجعة - حاسبة الأشكالتدرّب بنفسك: Playground لـ Swift