سؤال

هل يجب أن أكون قادرًا على إعداد مراقب على كائن وكيل، وتغيير ما يشير إليه كائن الوكيل، وما زلت قادرًا على ملاحظة التغييرات على الكائن الحقيقي؟

مثال قد يفسر هذا بشكل أفضل.النظر في ما يلي.

في الرأس:

@interface MyController : NSObject {   

  MyWidgetModel * aProxyObject;

}

في التهيئة أو الاستيقاظ من طريقة NIB:

-(void)awakeFromNib {

 // Init the proxy object. Could be as an empty widget 

 [aProxyObject addObserver:self 
                forKeyPath:@"widgetName"
                   options:NSKeyValueObservingOptionNew 
                   context:nil];

}

بعض الطرق الأخرى التي تغير الكائن:

-(void)changeWidget:(MyWidgetModel *)aNewWidget {

  aProxyObject = aNewWidget;

}

هذا لا يطلق أي تغييرات في aNewWidget.ومع ذلك، إذا قمت بنقل addObserver إلى بعد التعيين على النحو التالي، يعمل:

-(void)changeWidget:(MyWidgetModel *)aNewWidget {

   [aProxyObject removeObserver:self forKeyPath:@"widgetName"];

   aProxyObject = aNewWidget;

   [aProxyObject addObserver:self 
                  forKeyPath:@"widgetName"
                     options:NSKeyValueObservingOptionNew 
                     context:nil];
}

أفترض أن الحالة الأولى لا تعمل لأن المراقب يراقب مؤشر الذاكرة الخاص بمرجع كائن الوكيل، ونظرًا لعدم وجود كائن في وقت إضافة المراقب الوكيل ليس لديه ما يمكن ملاحظته.ومع ذلك، إذا قمت بتشغيل عنصر واجهة مستخدم ولاحظت ذلك، فقم بتعيين كائن الوكيل aNewWidget ما زال لا يلاحظ التغييرات إلا إذا قمت بإضافة المراقب بعد المهمة (وبالطبع خلق حاجة لإزالة المراقب عند تغيير الكائن).

أيضا، ماذا يحدث في هذا السيناريو إذا aNewWidget يتم تدميرها؟نظرًا لوجود المراقب على الوكيل، فهل ينفي هذا الحاجة إلى إزالة المراقب قبل تدمير الكائن؟(أفترض أنه لا).

من الناحية المثالية، أود أن أكون قادرًا على تعيين المراقب على الوكيل وتبديل أي مرجع لعنصر واجهة المستخدم أريده إلى كائن الوكيل دون الحاجة إلى القلق بشأن إضافة المراقب وإزالته ما لم يكن MyController يختفي الفصل وفي هذه الحالة يمكنني التعامل مع إزالة المراقب في Dealloc.

أي مساعدة / تعليقات / نصيحة موضع تقدير.

هل كانت مفيدة؟

المحلول

يجب أن يكون keyPath متوافقًا مع KVC.إذن هذا هو الكود:

@interface MyController : NSObject {   
  MyWidgetModel * aProxyObject;
}
@property (nonatomic, retain) MyWidgetModel * aProxyObject;

لا تنس تركيبه في ملف التنفيذ.ثم استخدم هذا الكود لإضافة المراقب:

[self addObserver:self 
            forKeyPath:@"aProxyObject"
               options:NSKeyValueObservingOptionNew 
               context:nil];

يرجى التحقق من التعديل الخاص بي.لقد قمت بتغيير التعيين للاحتفاظ به.ربما هو أفضل بالنسبة لك.يجب أن تحاول اختيار الأفضل بالنسبة لك.أريد فقط أن أقول أنه لا يهم في KVO.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top