3

「iPhone3のその他の開発」の同時実行の章で例を試していましたが、KVONSOperationQueueを期待どおりに動作させることができません。を作成し、以下を使用してその配列をNSOperationQueue観察します。operations

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

最初NSOperationのものがキューに追加されると、その基になるoperations配列(iOSのドキュメントではKVOに準拠していると記載されています)に追加されると思います。したがって、変更ディクショナリで、からのマッピングと、NSKeyValueChangeKindKeyからのマッピングを検索します。追加されたに。しかし、私はどんな種類の価値も見ていませんでした。NSKeyValueChangeInsertionNSKeyValueChangeNewKeyNSOperationNSKeyValueChangeInsertion

デバッガーがプロであり、すべてであることは知っていますが、ここにコピーするのに役立つものを用意するために、オブザーバーメソッドを次のように開始しました。

- (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私のサブクラスであり、単にプロジェクト名です。)ただし、メソッドは1つの操作を挿入すると2回呼び出され、両方とも種類の値が1であることに注意してください。さらに、追加されたアイテムではなく、配列自体のようです。NSOperationmainStalledNSKeyValueChangeSettingNSKeyValueChangeInsertionnewValueoldValue

何か案は?ありがとう!

4

2 に答える 2

3

ドキュメントによる-operationsと、KVOに準拠していますが、通知の詳細を指定しないでください。実際には、変更が発生したとだけ言われているようです。そのため、古い値と新しい値を比較して、何が挿入されたかを確認する必要があります。

これらの通知はどのスレッドでも送信できることを忘れないでください。

于 2010-12-23T17:54:22.030 に答える
-1

NSOperationQueueのoperationsプロパティには、変更可能なタイプがありません(戻りますNSArray*)。したがって、可変配列のインデックス付きの多数のコンプライアンスメソッドは実装されていないため、挿入イベントは表示されず、配列全体の変更イベントのみが表示されます。

編集

Shadowmatterは、実際に返されるオブジェクトがであるという事実を示していますNSMutableArray。ただし、これによって何も変更されません。まず、Appleのドキュメントはこの問題について明確です。不変オブジェクトを返すようにメソッドがアドバタイズされる場合は、APIを尊重する必要があります。isKindOf:それが本当に変更可能であるかどうかを確認するために使用してはならず、絶対に変更してはなりません。

APIによると、操作の戻り型は不変であるため、そのように扱う必要があります。この質問にとってさらに重要なのは、これは可変コレクションプロパティではないため、可変配列KVC値に準拠したキー値コーディングではないためです。可変のインデックス付きコレクションに準拠するには、クラスは次のことを行う必要があります。

  • -insertObject:in<Key>AtIndex:またはのいずれかまたは両方のメソッドを実装します-insert<Key>:atIndexes:
  • -removeObjectFrom<Key>AtIndex:またはのいずれかまたは両方のメソッドを実装します-remove<Key>AtIndexes:

(Apple KVCガイドから直接取得)

NSOperationQueueクラスの設計者は、operationsプロパティを不変として設計したため、上記のメソッドを意図的に省略しました。

于 2010-11-19T11:18:09.770 に答える