Objective c 用于整个对象属性的KVO
是否可以添加观察者,以便在任何受监视对象属性被修改时获得通知?例如:Objective c 用于整个对象属性的KVO,objective-c,ios,key-value-observing,Objective C,Ios,Key Value Observing,是否可以添加观察者,以便在任何受监视对象属性被修改时获得通知?例如: @interface OtherObject : NSObject @property (nonatomic) MyObject* myObject; @end 及 我想做一些类似的事情: [otherObject addObserver:self forKeyPath:@"myObject" options:0 con
@interface OtherObject : NSObject
@property (nonatomic) MyObject* myObject;
@end
及
我想做一些类似的事情:
[otherObject addObserver:self
forKeyPath:@"myObject"
options:0
context:nil]
如果修改了property1或property2,则会收到通知。如果我注册保持对象,它似乎不起作用(例如,在我修改属性1时,myObject并没有被真正修改,这在某种程度上是有意义的)。您可以使用一个函数来修改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,并对其他属性进行同样的处理
@interface MyObject : NSObject
@property (nonatomic) id masterProperty;
@property (nonatomic) unsigned int property1;
@property (nonatomic) unsigned int property2;
@end
但这将意味着为每个属性分别添加一个观察者。我可以想到两个选项
- 您可以创建一个单独的“主”属性,并使其依赖于所有其他属性
如果您观察到@interface MyObject : NSObject @property (nonatomic) id masterProperty; @property (nonatomic) unsigned int property1; @property (nonatomic) unsigned int property2; @end
,当任何属性发生更改时,都会收到通知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); }
-(void)addObserverForAllProperties:(NSObject*)observer 选项:(NSKeyValueObservingOptions)选项 上下文:(void*)上下文{ 无符号整数计数; objc_property_t*properties=class_copyPropertyList([self class],&count); 用于(大小i=0;i
- 鼓手回答的Swift版本,带有一个附加功能来删除观察结果(例如在
deinit
):
扩展对象{
func addObserverForAllProperties(
观察员:NSObject,
选项:NSKeyValueObservingOptions=[],
上下文:UnsafeMutableRawPointer?=nil
) {
PerformForallKeyPath{keyPath in
addObserver(观察者,forKeyPath:keyPath,选项:选项,上下文:上下文)
}
}
func removeObserverForAllProperties(
观察员:NSObject,
上下文:UnsafeMutableRawPointer?=nil
) {
PerformForallKeyPath{keyPath in
removeObserver(观察者,forKeyPath:keyPath,context:context)
}
}
func PerformForAllKeyPath(u操作:(字符串)->Void){
变量计数:UInt32=0
guard let properties=class\u copyPropertyList(object\u getClass(self),&count)else{return}
延迟{free(properties)}
对于0中的i..- (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);
}