إزالة المراقبين بأمان
تجنب التسربات والأعطال الناتجة عن المراقبين غير الصالحين.
إزالة المراقبين بأمان درس مجاني في Swift Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Swift Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Swift Academy 4 دروس في المجموع.
إزالة المراقبين بأمان
يجب إزالة المراقبين عند عدم الحاجة إليهم. فقد يعمل مراقب معلّق بعد زوال مالكه، مما يسبب أخطاء أو، مع واجهات API القديمة، حالات تعطل.
سبب أهمية الإزالة
كان يجب تاريخيًا إزالة المراقبين المعتمدين على selector داخل deinit لتجنب إرسال رسائل إلى كائن أُلغي تخصيصه.
import Foundation
class Watcher: NSObject {
override init() { super.init() }
deinit { NotificationCenter.default.removeObserver(self) }
}
print("Removes itself on deinit")removeObserver(self)
يلغي استدعاء removeObserver(self) تسجيل جميع عمليات المراقبة التي أنشأها ذلك الكائن، وذلك في استدعاء واحد.
import Foundation
class VM: NSObject {
func stop() { NotificationCenter.default.removeObserver(self) }
}
VM().stop()
print("Removed all observations for self")إزالة اسم محدد
يمكنك إزالة مراقبة واحدة فقط بتمرير الاسم وobject، مع إبقاء عمليات المراقبة الأخرى كما هي.
import Foundation
let center = NotificationCenter.default
let obj = NSObject()
let name = Notification.Name("ping")
center.removeObserver(obj, name: name, object: nil)
print("Removed a specific observation")مراقبون معتمدون على token
تعيد addObserver المعتمدة على closure token غير مكشوف التفاصيل. احتفظ به، ثم أزل المراقب باستخدام ذلك token.
import Foundation
let center = NotificationCenter.default
let name = Notification.Name("ping")
let token = center.addObserver(forName: name, object: nil, queue: nil) { _ in }
center.removeObserver(token)
print("Removed via token")تخزين token
خزّن token في خاصية حتى يظل موجودًا طوال الفترة التي تريد فيها المراقبة، ثم أزله عند الانتهاء.
import Foundation
class Model {
var token: NSObjectProtocol?
func start() {
token = NotificationCenter.default.addObserver(
forName: Notification.Name("x"), object: nil, queue: nil) { _ in }
}
func stop() {
if let t = token { NotificationCenter.default.removeObserver(t) }
}
}
let m = Model(); m.start(); m.stop()
print("Lifecycle managed")التنظيف التلقائي باستخدام deinit
أزل token داخل deinit حتى تنتهي المراقبة عند إلغاء تخصيص مالكها.
import Foundation
class Owner {
var token: NSObjectProtocol?
deinit { if let t = token { NotificationCenter.default.removeObserver(t) } }
}
print("Token removed on deinit")ملاحظة حول دورة الحياة الحديثة
في بيئات التشغيل الحديثة، تُزال المراقبات المضافة باستخدام واجهة block تلقائيًا عند إلغاء تخصيص token، لكن الإزالة الصريحة تظل الخيار الآمن والواضح.
import Foundation
// Holding the token in a property controls its lifetime.
class C { var token: NSObjectProtocol? }
print("Token lifetime equals observation lifetime")تجنب دورات الاحتفاظ
إذا التقطت دالة closure الخاصة بالمراقب self بقوة، فاستخدم [weak self] لتجنب دورة احتفاظ تمنع إلغاء تخصيصه.
import Foundation
class VM {
var token: NSObjectProtocol?
func start() {
token = NotificationCenter.default.addObserver(
forName: Notification.Name("x"), object: nil, queue: nil) { [weak self] _ in
self?.handle()
}
}
func handle() { print("handled") }
}
VM().start()الإزالة المزدوجة آمنة
إن إزالة مراقب أُزيل بالفعل لا تسبب ضررًا، لذا لن يؤدي التنظيف الاحترازي إلى تعطل التطبيق.
import Foundation
let center = NotificationCenter.default
let obj = NSObject()
center.removeObserver(obj)
center.removeObserver(obj) // no harm
print("Safe to remove twice")خلاصة أفضل الممارسات
فضّل دوال closure المعتمدة على token، وخزّن token، وأزله داخل deinit، والتقط self باستخدام weak. فهذا يحافظ على صحة دورات حياة المراقبة.
import Foundation
class Best {
var token: NSObjectProtocol?
deinit { token.map { NotificationCenter.default.removeObserver($0) } }
}
print("Followed best practices")تحقق سريع
كيف تزيل مراقبًا معتمدًا على closure أُضيف باستخدام addObserver(forName:...)؟
مراجعة
أزل دائمًا المراقبين الذين لم تعد بحاجة إليهم. استخدم removeObserver(self) مع المراقبين المعتمدين على selector، واستخدم token المُعاد مع المراقبين المعتمدين على closure، وخزّن token، ونظّف الموارد داخل deinit، والتقط self باستخدام weak. التالي: مقارنة نمط المراقب بالبدائل.
الأسئلة الشائعة
هل درس «إزالة المراقبين بأمان» مجاني؟
نعم — نص درس «إزالة المراقبين بأمان» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Swift Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Swift Academy 4 دروس في المجموع.
ماذا ستتعلم في «إزالة المراقبين بأمان»؟
تجنب التسربات والأعطال الناتجة عن المراقبين غير الصالحين. تتمرن على Swift Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Swift Academy؟
لا تُشترط خبرة سابقة. Swift Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «إزالة المراقبين بأمان»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Swift Academy هذا؟
نعم. كل درس في Swift Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- نشر الإشعارات ومراقبتها
- حمولات userInfo للإشعارات
- إزالة المراقبين بأمان
- بدائل نمط المراقب