المواقع الممكنة لاتصال طرق AddObserver و RemoveObserver
-
03-07-2019 - |
سؤال
لدي حالة يرسل فيها عرض الطفل إشعارًا إلى عرض الوالدين. الآن أنا أتصل addObserver:
في viewWillAppear:
و removeObserver:
في viewWillDisappear:
. لكنني أعتقد أن هذا غير صحيح منذ ذلك الحين viewWillAppear:
المكالمات عند تحديث العرض.
[[NSNotificationCenter defaultCenter] addObserver: (id)observer selector: (SEL)aSelector name: (NSString *)aName object: (id)anObject];
[[NSNotificationCenter defaultCenter] removeObserver: (id)observer name: (NSString *)aName object: (id)anObject];
شكرًا.
المحلول
في الواقع ، هذه فكرة سيئة. عندما تنخفض الذاكرة ، قد يتم إرسال وحدة تحكم العرض الخاصة بك إلى تحذير من الذاكرة. السلوك الافتراضي في هذه الحالة هو مسح عرضك (إذا لم تكن على الشاشة حاليًا). في هذه الحالة ، يمكنك إرسال رسالة ViewDidload للمرة الثانية (بعد حدث الذاكرة ، عندما يتم إعادة عرضك على الشاشة بواسطة وحدة تحكم التنقل.) وبالتالي سيكون لديك تسجيلان لنفس الكائن ، ولكن إزالة واحدة فقط (في Dealloc)
حل أفضل هو تعيين علامة تقول أنك قمت بالتسجيل ، أو للتسجيل في طريقة init الخاصة بك.
نصائح أخرى
أعتقد أن المواقف الصحيحة للتسجيل في الإخطار هي viewDidLoad
الطريقة ، والموضع الصحيح لإلغاء التسجيل لنفس الإخطارات dealloc
طريقة.
على حق بن - لكنني وجدت آخر ، محتمل ، هش ، حول ذلك. لقد اكتشفت هذا للتو لأنني كنت أحصل إلى الأبد على "... تم تعامله بينما كان مراقبون القيمة الرئيسية لا يزالون مسجلين معها"
لا أعرف لماذا - ولكن عندما كان لدي Addobserver في طريقة init الخاصة بي ، و removeObserver في طريقة Dealloc الخاصة بي - ما زلت أحصل على KVO لا يزال يتم ملاحظته. صعدت والتحقق من أن removeObserver كان يتم استدعاؤه بشكل صحيح.
لقد نقلت addobserver إلى طريقة ViewDidload بدلاً من ذلك ، ويبدو أن ذلك يعمل.
تركت removeObserver في lookdidunload و في Dealloc ؛ لكني لا أحب ذلك لأنه ليس متوازنًا. ولكن في ظل الظروف العادية ، لا يتم استدعاء تحميل ViewDidunload الخاص بي - هذه مجرد حماية في حالة حصولني على إشعار ذاكرة منخفض.
لكن أستطيع أن أرى محتملة الدخول في الموقف الذي يأتي فيه حدث ذاكرة منخفض ، ويتم استدعاء ViewDidunload. إذا قمت بعد ذلك بالضغط على Dealloc في وقت ما بعد ذلك (قبل أن أضغط على FiewDidload مرة أخرى) ، سأتصل بـ RemoveObserver مرتين!
لذلك ، أعتقد أنني سأبقيها في Leydiddload ، و Dealloc الخاص بي.
ما زلت لا أعرف لماذا لا يعمل بشكل صحيح إذا قمت بعمل AddObserver في طريقة init الخاصة بي.