我试图观察UINavigationController的(readonly)visibileViewController属性但没有成功。我能够成功地观察到我自己定义的readwrite属性,以便在另一个类上进行测试。
是否可以观察只读属性?
答案 0 :(得分:22)
是的,可以观察只读属性。但是,如果声明该属性的对象以不是键值观察compliant 的方式更改该属性的值(例如,更改实例变量支持的值)直接属性而不发送willChangeValueForKey:
和didChangeValueForKey:
通知)然后KVO系统不会自动通知观察者。如果您可以验证此属性的值是否正在更改并且您的观察者未收到通知,我会(1)在此处或其他地方发布一些代码,以便其他人可以帮助您找到您的错误,以及(2)如果没有错误你的代码,在Apple的radar上提交了一个错误。
答案 1 :(得分:15)
是。在您自己的类中实现它的一种简单方法是在.h文件中将该属性声明为readonly,并在.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 :(得分:2)
你当然可以观察只读属性,但要注意,为了使KVO工作,你需要符合KVC - 这意味着使用setter / getter作为属性(因为你只读,你没有得到通过@synthesize
)免费设置setter或使用属性的-setValue:forKey:
方法。
答案 3 :(得分: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
答案 4 :(得分:-2)
使用NSKeyValueObserving绝对可以做到这一点。属性实际上具有getter / setter实现,它们只是由编译器通过Objective-C类实现中的@synthesize关键字为您完成的。由于键值观察协议基于Objective-C中的标准getter / setter约定,因此观察属性可以正常工作。文档(上面链接)甚至通过名称提及类属性:
“NSKeyValueObserving(KVO)非正式协议定义了一种机制,允许对象通知其他对象的指定属性的更改。”