11

オブザーバーを追加して、監視対象オブジェクトのプロパティが変更された場合に通知を受けることはできますか? 例えば:

@interface OtherObject : NSObject

@property (nonatomic) MyObject* myObject;

@end

@interface MyObject : NSObject

@property (nonatomic) unsigned int property1;
@property (nonatomic) unsigned int property2;

@end

私は次のようなことをしたいと思います:

[otherObject addObserver:self
               forKeyPath:@"myObject"
                  options:0
                  context:nil]

property1 または property2 が変更された場合に通知を受け取ります。保持オブジェクトを登録すると機能しないようです (たとえば、property1 を変更しても myObject は実際には変更されないため、どういうわけか理にかなっています)。

4

3 に答える 3

15

2つの選択肢が考えられます。

  • 別の「マスター」プロパティを作成して、他のすべてのプロパティに依存させることができます。

    @interface MyObject : NSObject
    @property (nonatomic) id masterProperty;
    @property (nonatomic) unsigned int property1;
    @property (nonatomic) unsigned int property2;
    @end
    

     </p>

    + (NSSet *)keyPathsForValuesAffectingMasterProperty {
        return [NSSet setWithObjects:@"property1", @"property2", nil];
    }
    

    観察するmasterPropertyと、プロパティのいずれかが変更されたときに通知されます。

  • Objective-C ランタイムを使用して、すべてのプロパティのリストを取得し、それらすべてを観察します。

    - (void)addObserverForAllProperties:(NSObject *)observer
                                options:(NSKeyValueObservingOptions)options
                                context:(void *)context {
        unsigned int count;
        objc_property_t *properties = class_copyPropertyList([self class], &count);
        for (size_t i = 0; i < count; ++i) {
            NSString *key = [NSString stringWithCString:property_getName(properties[i])];
            [self addObserver:observer forKeyPath:key 
                      options:options context:context];
        }
        free(properties);
    }
    
于 2012-10-01T12:55:17.190 に答える
2

あなたができることは、myObjectの特定のプロパティを変更する機能を持つことです...

-(void)setMyObjectName:(NSString*)name;

そして、関数にこのコードがあります...

- (void)setMyObjectName:(NSString*)name
{
    [self willChangeValueForKey:@"myObject"];

    myObject.name = name;

    [self didChangeValueForKey:@"myObject"];
}

これにより、myObject のプロパティが変更されたときにオブザーバーに通知されます。

これを行う必要がある場合はいつでもこのパターンを使用すると、myObject の変更について通知を受け取ることができます。

::編集::そうは言っても、使用できるはずです...

[otherObject addObserver:self
              forKeyPath:@"myObject.property1"
                 options:0
                 context:nil];

それは property1 を監視し、他のプロパティに対して同じことを行います。

ただし、これは各プロパティのオブザーバーを個別に追加することを意味します。

于 2012-10-01T12:41:02.527 に答える