Кво для свойств всего объекта


Можно ли добавить наблюдателя, чтобы получать уведомления, если какие-либо свойства объекта наблюдения изменяются? Например:

@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]

И получать уведомления, если изменяется свойство 1 или свойство 2. Это, кажется, не работает, если я регистрирую удерживающий объект (как-то имеет смысл, потому что myObject на самом деле не изменяется, когда я изменяю property1, например).

2 10

2 ответа:

Я могу придумать два варианта.

  • Вы можете создать отдельное свойство "master" и сделать его зависимым от всех других ваших свойств.

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

    + (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);
    }
    

Что вы могли бы сделать, так это иметь функцию для изменения определенного свойства 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];

И что будет соблюдать свойство1 и делать то же самое Форт другое свойство.

Но это будет означать добавление наблюдателя для каждого свойства в отдельности.