[document doSomething]
私はすぐに実行したい[document isBusy]
です false. それを行う最良の方法は何ですか?while ループで試してみましたが、次のコードが遅れてしまいます。これは私が望んでいるものではありません。
3 に答える
アクションが文書モデルのセマンティックである場合
あなたの質問から、isBusy
との両方がドキュメントの機能であり、 falseになるときdoSomething
のアクションは、ドキュメント モデルのセマンティックであるように見えるため、ドキュメント モデルによって実装する必要があります。つまり、次のようなものです。doSomething
isBusy
- (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];
}
isBusy
関連付けられたセッター メソッドがある場合は、doSomething
そのセッターを呼び出すことができます。より良いオプションは、Key Value Observingを使用して の値を観察し、isBusy
変化したときにアクションを実行することです。
KVC/KVO (Key Value Coding および Key Value Observation) を使用します。この件については、Apple のドキュメントで詳しく説明されています。KVO と KVC は、問題に対する多くの解決策を提供する基本的なプログラミング手法です。