5

私は、動的プロパティがプロパティの影響を受けるKVO 対応クラス (と呼びますObservee)を持っています。プロパティ間の依存関係は、実装メソッドによって定義されます。affectedValueaffectingValue+keyPathsForValuesAffectingAffectedValue

のサブクラスでない限り 、期待どおりに変更され たaffectingValue通知に値を設定します。完全な例は次のとおりです。affectedValue OvserveeNSObjectController

@interface Observee : NSObject // or NSObjectController
@property (readonly, strong, nonatomic) id affectedValue;
@property (strong, nonatomic) id affectingValue;
@property (strong, nonatomic) NSArrayController *arrayController;
@end

@implementation Observee

@dynamic affectedValue;
- (id)affectedValue { return nil; }

+ (NSSet *)keyPathsForValuesAffectingAffectedValue {
  NSLog(@"keyPathsForValuesAffectingAffectedValue called");
  return [NSSet setWithObject:@"affectingValue"];
}

@end

@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (strong, nonatomic) Observee *observee;
@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)notification {
  self.observee = [[Observee alloc] init];
  [self.observee addObserver:self
                  forKeyPath:@"affectedValue"
                     options:NSKeyValueObservingOptionNew
                     context:NULL];
  NSLog(@"setting value to affectingValue");
  self.observee.affectingValue = @42;
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {
  NSLog(@"affected key path = %@", keyPath);
}

@end

この例は正常に機能し、次のように出力されObserveeますNSObject

keyPathsForValuesAffectingAffectedValue called
setting value to affectingValue
affected key path = affectedValue

しかし、Observee派生する場合NSObjectController:

keyPathsForValuesAffectingAffectedValue called
setting value to affectingValue

(「影響を受けるキーパス=影響を受ける値」が存在しないことに注意してください。)

どちらの場合も呼び出されるようですkeyPathsForValuesAffectingAffectedValueが、後者ではノーオペレーションです。

また、(のサブクラス) のインスタンスを含むNSObjectControllerキー パスは、次のような他のキー パスには影響しません。

@implementation SomeObject

// `someValue` won't be affected by `key.path.(snip).arrangedObjects`
+ (NSSet *)keyPathsForValuesAffectingSomeValue {
  return [NSSet setWithObject:@"key.path.involving.anNSArrayController.arrangedObjects"];
}

@end

このような場合、キー パス間の依存関係を宣言するにはどうすればよいですか? そして、なぜこのすべてが起こっているのですか?

(はい、友人のことは知っていwill/didChangeValueForKey:ますが、影響を与えるすべてのキー パスを (別の) セッターでまとめるのはひどいので、避けたいと思います。)

4

1 に答える 1