0

[document doSomething]私はすぐに実行したい[document isBusy]です false. それを行う最良の方法は何ですか?while ループで試してみましたが、次のコードが遅れてしまいます。これは私が望んでいるものではありません。

4

3 に答える 3

3

アクションが文書モデルのセマンティックである場合

あなたの質問から、isBusyとの両方がドキュメントの機能であり、 falseになるときdoSomethingのアクションは、ドキュメント モデルのセマンティックであるように見えるため、ドキュメント モデルによって実装する必要があります。つまり、次のようなものです。doSomethingisBusy

- (void) setIsBusy:(BOOL)flag
{
   if(flag != _isBusy) // check if this is a change
   {
      _isBusy = flag;
      if(flag)
      {
         // doSomething, or schedule doSomething if it is a long operation etc., e.g.
         [self doSomething];
      }
   }
}

KVO を使用して 1 つのオブジェクトにセマンティクスを実装するのはおそらく珍しいことですが、便利な場合もあります。この場合、直接アクションを間接アクションに置き換えます。KVO はdoSomething上記のサンプル コードとまったく同じポイントで実行され、KVO のセットアップに関連する と のsetIsBusy間に多数の中間システム メソッドが存在するだけです。doSomething

アクションがドキュメントのクライアントのセマンティックである場合

もちろん、これら 2 つの間のリンクがドキュメント モデルから独立している場合、つまり、ドキュメントのクライアントのセマンティックである場合は、KVO が適切であり、クライアントに実装されます。クライアントは、ドキュメントのオブザーバーとして登録します。つまり、次のようになります。

[document addObserver:self
           forKeyPath:@"isBusy"
              options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
              context:NULL];

クライアントのメソッドで。次に、変更の通知を受け取ったときにクライアントで適切なアクションを実行します。

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
   if ([keyPath isEqual:@"isBusy"] && object == document)
      [document doSomething;
   else
      [super observeValueForKeyPath:keyPath
                           ofObject:object
                             change:change
                            context:context];
}
于 2012-11-03T18:05:03.490 に答える
3

isBusy関連付けられたセッター メソッドがある場合は、doSomethingそのセッターを呼び出すことができます。より良いオプションは、Key Value Observingを使用して の値を観察し、isBusy変化したときにアクションを実行することです。

于 2012-11-03T15:41:16.117 に答える
2

KVC/KVO (Key Value Coding および Key Value Observation) を使用します。この件については、Apple のドキュメントで詳しく説明されています。KVO と KVC は、問題に対する多くの解決策を提供する基本的なプログラミング手法です。

于 2012-11-03T15:45:48.097 に答える