2

KVO 通知を生成するために setFinished: を実装する NSOperation サブクラスがあります。

-(void)setFinished:(BOOL)isFinished
{
    LogError(@"%@ will will changing isFinished to %d",self,isFinished);
    [self willChangeValueForKey:@"isFinished"];
    LogError(@"%@ did will changing isFinished to %d",self,isFinished);
    _isFinished = isFinished;
    LogError(@"%@ will did changing isFinished to %d",self,isFinished);
    [self didChangeValueForKey:@"isFinished"];
    LogError(@"%@ did did changing isFinished to %d",self,isFinished);
}

また、オブザーバーを操作に一度だけ追加したことも確かです。

奇妙なことに、observeValueForKeyPath:ofObject:change:context:このオブジェクトのisFinishedキーパスが 2 回呼び出され、ログを参照すると、setFinished:1 回addObserver:forKeyPath:だけ呼び出され、この操作では 1 回だけ呼び出されることがあります。

また、そのシーケンスは次のようなものであることがわかりました。

will will changing isFinished to 1
did will changing isFinished to 1
will did changing isFinished to 1
calling observeValueForKeyPath for object
did did changing isFinished to 1
calling observeValueForKeyPath for object

誰か手がかりを教えてください。

4

2 に答える 2

-1

「setFinished:」を実装する必要はありません。

KVO メソッドのobserveValueForKeyPath:ofObject:change:context: は、setFinished: から 1 回呼び出されます。

[self willChangeValueForKey:@"isFinished"];

解決策は、[self willChangeValueForKey:@"isFinished"]; を呼び出すことです。変数 'finished' を次のように設定した場合のみ:

[self willChangeValueForKey:@"isFinished"];
self.finished = YES;
[self didChangeValueForKey:@"isFinished"];

setFinished をオーバーライドせずに:

于 2013-06-24T11:14:06.503 に答える