19

我试图观察 UINavigationController 的(只读)visibileViewController 属性,但没有成功。我能够成功地观察到我自己定义的用于在另一个类上进行测试的读写属性。

是否可以观察只读属性?

4

5 回答 5

22

是的,可以观察只读属性。但是,如果声明该属性的对象以不符合Key-Value ObservingwillChangeValueForKey:的方式更改该属性的值(例如,在没有 seding和通知的情况下直接更改支持该属性的实例变量的值didChangeValueForKey:),那么观察者将不会KVO 系统会自动通知。如果您可以验证此属性的值正在更改并且没有通知您的观察者,我会(1)在此处或其他地方发布一些代码,以便其他人可以帮助您找到您的错误,以及(2)如果没有错误您的代码,在 Apple 的雷达上提交错误。

于 2009-02-14T21:08:41.377 回答
15

是的。在您自己的类中实现它的一种简单方法是在 .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
于 2012-08-11T21:24:00.927 回答
2

您当然可以观察只读属性,但请注意,为了使 KVO 工作,您需要符合 KVC - 这意味着对属性使用 setter/getter(因为您是只读的,所以您不会免费获得 setter via @synthesize) 或属性的-setValue:forKey:方法。

于 2009-02-16T07:24:43.717 回答
0

一个稍微不同的答案:

@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
于 2014-05-10T15:00:42.417 回答
-2

使用NSKeyValueObserving这绝对是可能的。属性实际上具有 getter/setter 实现,它们只是由编译器通过 Objective-C 类实现中的 @synthesize 关键字为您完成的。由于键值观察协议基​​于 Objective-C 中的标准 getter/setter 约定,因此观察属性可以正常工作。文档(上面链接)甚至按名称提到了类属性:

“NSKeyValueObserving (KVO) 非正式协议定义了一种机制,允许在其他对象的指定属性发生更改时通知对象。”

于 2009-02-14T21:00:25.860 回答