سؤال

كنت أعمل من خلال مثال في الفصل التزامن من "More iPhone 3 Development" ، ولا يمكنني الحصول على KVO على NSOperationQueue العمل كما هو متوقع. أنا إنشاء NSOperationQueue ومراقبة operations صفيف باستخدام:

NSOperationQueue *newQueue = [[NSOperationQueue alloc] init];
self.queue = newQueue;
[newQueue release];
[queue addObserver:self
        forKeyPath:@"operations"
           options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
           context:NULL];

عندما يكون الأول NSOperation يضاف إلى قائمة الانتظار ، وأتوقع أن تتم إضافتها إلى الأساس operations Array (التي تقول وثائق iOS إنها متوافقة مع KVO) وبالتالي ، في قاموس التغيير ، لإيجاد رسم خرائط من NSKeyValueChangeKindKey ل NSKeyValueChangeInsertion, ، جنبا إلى جنب مع رسم الخرائط من NSKeyValueChangeNewKey إلى المضافة NSOperation. لكنني لم أر أي نوع من القيمة NSKeyValueChangeInsertion.

أعلم أن تصحيح الأخطاء مؤيد وجميع ، ولكن من مصلحة شيء مفيد لنسخه هنا ، بدأت طريقة المراقب الخاصة بي مع:

- (void) observeValueForKeyPath:(NSString *)keyPath
                       ofObject:(id)object
                         change:(NSDictionary *)change
                        context:(void *)context {
  NSNumber *kind = [change objectForKey:NSKeyValueChangeKindKey];
  NSObject *newValue = [change objectForKey:NSKeyValueChangeNewKey];
  NSObject *oldValue = [change objectForKey:NSKeyValueChangeOldKey];
  NSIndexSet *indexes = [change objectForKey:NSKeyValueChangeIndexesKey];
  NSLog(@"kind=%d, newValue=%@, oldValue=%@, indexes=%@",
       [kind integerValue], newValue, oldValue, indexes);

وهذا يطبع:

2010-11-18 20:01:56.249 Stalled[2692:6f07] kind=1, newValue=(
    "<SquareRootOperation: 0x5f51b40>"
), oldValue=(
), indexes=(null)

2010-11-18 20:01:56.250 Stalled[2692:6f07] kind=1, newValue=(
    "<SquareRootOperation: 0x5f51b40>"
), oldValue=(
    "<SquareRootOperation: 0x5f51b40>"
), indexes=(null)

(SquareRootOperation هو ببساطة الفئة الفرعية الخاصة بي من NSOperation هذا يتجاوز main بشكل مناسب ، و Stalled هو ببساطة اسم المشروع.) ولكن لاحظ أن الطريقة تسمى مرتين عند إدخال عملية واحدة ، وفي كلتا الحالتين بقيمة لطيفة 1 ، وهي NSKeyValueChangeSetting, ، ليس NSKeyValueChangeInsertion. بالإضافة إلى ذلك، newValue و oldValue يبدو أن الصفيف نفسه ، وليس العنصر المضافة.

أيه أفكار؟ شكرًا!

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

المحلول

تقول المستندات -operations هو متوافق مع KVO ، ولكن لا تحدد التفاصيل التي ستكون عليها الإخطارات. في الممارسة العملية ، يبدو أنك قيل لك فقط أن التغيير قد حدث ، لذلك يجب أن تقارن القيم القديمة والجديدة لمعرفة ما تم إدراجه.

لا تنسى أن هذه الإشعارات يمكن إرسالها إليك على أي موضوع!

نصائح أخرى

خاصية عمليات nsoperationQueue لا تحتوي على نوع قابل للتغيير (يعود NSArray*). وبالتالي ، فهي لا تنفذ أساليب الامتثال المفهرسة للصفائف القابلة للتغيير ، لذا لن ترى أبدًا أحداث الإدراج ، فقط حدث التغيير للمصفوفة بأكملها.

تعديل

لقد طرح Shadowmatter حقيقة أن الكائن الذي تم إرجاعه فعليًا هو NSMutableArray. هذا لا يغير أي شيء. أولاً، وثائق Apple واضح بشأن هذه القضية. إذا تم الإعلان عن طريقة لإرجاع كائن ثابت ، فيجب عليك احترام واجهة برمجة التطبيقات. يجب ألا تستخدم isKindOf: لمعرفة ما إذا كان قابلاً للتغيير حقًا ويجب بالتأكيد عدم تغييره.

تقول واجهة برمجة التطبيقات إن نوع إرجاع العمليات غير قابل للتغيير ، وبالتالي يجب أن تعامله على هذا النحو. الأهم من ذلك بالنسبة لهذا السؤال ، لأنه ليس خاصية مجموعة قابلة للتغيير ، فهي ليست متوافق مع ترميز القيمة الرئيسية لقيم الصفيف القابلة للتبديل KVC. للامتثال لجمع المفهرسة القابلة للتغيير ، يتعين على الفصل

  • تنفيذ واحدة أو كليهما من الأساليب -insertObject:in<Key>AtIndex: أو -insert<Key>:atIndexes:.
  • تنفيذ واحدة أو كليهما من الأساليب -removeObjectFrom<Key>AtIndex: أو -remove<Key>AtIndexes:.

(مأخوذة مباشرة من دليل Apple KVC)

مصمم NSOperationQueue فئة صمم operations الخاصية على أنها غير قابلة للتغيير وبالتالي تعمد الأساليب المذكورة أعلاه.

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