Можно ли наблюдать свойство readonly объекта в Cocoa Touch? - PullRequest
19 голосов
/ 14 февраля 2009

Я пытался наблюдать (только для чтения) свойство visibileViewController UINavigationController, но безуспешно. Мне удалось успешно определить свойство readwrite, которое я определил для тестирования другого класса.

Можно ли наблюдать за атрибутами только для чтения?

Ответы [ 5 ]

22 голосов
/ 15 февраля 2009

Да, можно наблюдать свойства только для чтения. Однако, если объект, который объявляет это свойство, вносит изменения в значение этого свойства способом, который не Наблюдение значения ключа Соответствует (например, изменяет значение резервной копии переменной экземпляра) это свойство напрямую, без потери уведомлений willChangeValueForKey: и didChangeValueForKey:), тогда наблюдатели не будут автоматически уведомлены системой KVO. Если вы можете проверить, что значение этого свойства изменяется, а ваши наблюдатели не уведомляются, я (1) опубликую некоторый код здесь или в другом месте, чтобы другие могли помочь вам найти вашу ошибку, и (2) если в ней нет ошибки свой код, подайте ошибку на Apple radar .

15 голосов
/ 12 августа 2012

Да. Простой способ реализовать его в своем собственном классе - объявить свойство как доступное только для чтения в файле .h и повторно объявить его как доступный для записи в закрытом интерфейсе в файле .m. Таким образом, вы можете синтезировать и получать уведомления об изменениях автоматически.

В файле .h:

@interface MyClass : NSObject
@property (nonatomic, readonly) BOOL foo;
@end

В файле .m

@interface MyClass ()
@property (nonatomic, readwrite) BOOL foo;
@end

@implementation MyClass

@synthesize foo;

- (void)bar {
    // Observers will see the change
    self.foo = YES;
}

@end
2 голосов
/ 16 февраля 2009

Вы, конечно, можете наблюдать свойства только для чтения, но имейте в виду, что для работы KVO необходимо быть совместимым с KVC - что означает использование для свойства либо метода set / getter (так как вы только для чтения, вы не получаете Установщик бесплатно через @synthesize) или метод -setValue:forKey: свойства.

0 голосов
/ 10 мая 2014

Немного другой ответ:

@interface MyClass : NSObject
@property (nonatomic, readonly) BOOL foo;
@end

В файле .m

@interface MyClass ()
@property (nonatomic, readwrite) BOOL foo;
@end

@implementation MyClass

+ (NSSet *)keyPathsForValuesAffectingFoo {
    return [[NSSet alloc] initWithObjects:NSStringFromSelector(@selector(foo)), nil];
}

@end
0 голосов
/ 15 февраля 2009

Это определенно возможно при использовании NSKeyValueObserving . Свойства на самом деле имеют реализации getter / setter, они просто создаются для вас компилятором через ключевое слово @synthesize в реализации классов Objective-C. Так как протокол наблюдения значения ключа основан на стандартных соглашениях получателя / установщика в Objective-C, свойства наблюдения работают нормально. В документации (ссылка выше) даже упоминаются свойства класса по имени:

"Неформальный протокол NSKeyValueObserving (KVO) определяет механизм, который позволяет объектам получать уведомления об изменениях в указанных свойствах других объектов."

...