KVO での自動変更通知の抑制(独自の実装の方法)

KVO (Key-Value Observing) でプロパティの変更にともない自動的に willChangeValueForKey: / didChangeValueForKey:(または willChange:valuesAtIndexes:forKey: / didChange:valuesAtIndexes:forKey:)が呼ばれることで、オブザーバーに observeValueForKeyPath:ofObject:change:context: メソッドの呼び出しという形で通知が送られる。

より細かく通知を制御したい場合には、この自動的なメカニズムを抑制する必要がある。この場合、+automaticallyNotifiesObserversForKey: を実装して NO を返し、プロパティの設定のコードの中で willChangeValueForKey: / didChangeValueForKey: を呼び出し変更を通知する。

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)theKey 
{
    BOOL automatic = NO;
 
    if ([theKey isEqualToString:@"anyProperty"]) { 
        automatic = NO;
    } else { 
        automatic = [super automaticallyNotifiesObserversForKey:theKey];
    } 
    return automatic;
}

ところが、クラスカテゴリを使用する場合にはこの方法が使えない。

別の方法として、+automaticallyNotifiesObserversOf を実装することが可能で、この場合、ソースコード上もプロパティの @synthesize などもひとそろいで記述することもできる。

@synthesize anyProperty = _anyProperty;

+ (BOOL)automaticallyNotifiesObserversOfAnyPropery
{
    return NO;
}

- (NSUInteger)anyProperty
{
    return self->_anyProperty;
}

- (void)setAnyProperty:(NSUInteger)newValue
{
    if (some condition) {
        assert(NO);
    } else {
        if (newValue != self->_anyProperty) {
            [self willChangeValueForKey:@"anyProperty"];
            self->_anyProperty = newValue;
            [self didChangeValueForKey:@"anyProperty"];
        }
    }
}
カテゴリー: 開発 Tips (32): Key-Value Coding/Observing タグ: パーマリンク

コメントは停止中です。