Ios NSObject中的属性更改通知

Ios NSObject中的属性更改通知,ios,properties,nsnotificationcenter,key-value-coding,Ios,Properties,Nsnotificationcenter,Key Value Coding,是否可以通知对象中所有属性的更改?我希望在NSObject中的某个属性发生更改时调用选择器 到目前为止,我只看到了keypathsforvaluesafectingvalueforkey:,这不是我想要的,但它始终显示在我的搜索结果中 我目前的具体目标是创建一个“FilterModel”,它具有特定过滤器特性的属性。当任何属性发生更改时,我希望使用新筛选的结果更新UITableView。根据您的需要,这两个选项中的一个可能是您要查找的 KVO观测 KVO提供了一个框架,用于自动侦听属性更改,而无

是否可以通知对象中所有属性的更改?我希望在NSObject中的某个属性发生更改时调用
选择器

到目前为止,我只看到了
keypathsforvaluesafectingvalueforkey:
,这不是我想要的,但它始终显示在我的搜索结果中


我目前的具体目标是创建一个“FilterModel”,它具有特定过滤器特性的属性。当任何属性发生更改时,我希望使用新筛选的结果更新
UITableView

根据您的需要,这两个选项中的一个可能是您要查找的

KVO观测 KVO提供了一个框架,用于自动侦听属性更改,而无需修改getter和setter。只需通过以下方式将您的收听对象添加为观察者或目标对象:

addObserver:forKeyPath:options:context:

然后在观察者的实现中,实现:

observeValueForKeyPath:of对象:更改:上下文:

并检查捕获通知的路径是否与所需属性匹配。有关接收KVO通知的更多信息,请参阅。有关KVO观测概念的更多详细信息和更好的可视化,请参阅

手动通知 如果您想微调您感兴趣的更改,无论何时通过setter对您感兴趣的对象进行更改,请通过以下方式发布通知:

postNotificationName:object:userInfo:

这将允许您精确地定制您感兴趣的更改,而不是希望通过类似
keypathsforvaluesfecutingvalueforkey:
的方式获得您想要的确切行为。然后,您可以通过以下方式通过在相关视图中侦听命名通知来捕获这些通知:

addObserver:selector:name:object:


您可以阅读有关在上发布通知的更多信息

您可以通过使用Objective-C runtime查询对象的属性列表并将自定义类注册为它们的观察者来实现这一点

id yourObject;

objc_property_t* properties = class_copyPropertyList([yourObject class], &count);
NSMutableArray* propertyArray = [NSMutableArray arrayWithCapacity:count];
for (int i = 0; i < count ; i++)
{
    const char* propertyName = property_getName(properties[i]);
    NSString *stringPropertyName = [NSString  stringWithCString:propertyName encoding:NSUTF8StringEncoding]];
    [yourObject addObserver:self forKeyPath:stringPropertyName options:NSKeyValueObservingOptionNew context:nil];
}
-(id)init
{
if(self=[super init])
{
无符号整数属性计数;
objc_property_t*properties=class_copyPropertyList([self class],&propertyCount);
对于(int i=0;i
@StephenJ谢谢!但这真的是最好的方法吗?这似乎相当老套。这个答案中的解决方案确实老套,如果说是聪明的话。它的一个缺点是它只适用于声明的
@properties
。带有通常声明的访问器方法的“旧”样式属性(完全有效,并自动发出KVO通知)将不在其范围内。@RileyE请将您的解决方案作为答案发布,而不是作为问题的一部分。@AaronBrager好的。很抱歉。我不想从帮助我达到这一点的当前答案中删除。在这一点上,我还不如重写setter并执行更改。我希望有一种方法可以让模型在任何组件发生更改时执行触发器/通知,而不必覆盖每个单独的属性。有一个可以应用于所有类似情况的iOS解决方案是很方便的?这可能更符合您的要求。这不就是覆盖setter和getter吗?覆盖属性的getter和setter吗?我不这么认为,您只需通过
addObserver:forKeyPath:options:context:
将侦听对象添加为观察者或目标对象即可。然后在ObserverValueForkeyPath中执行
ObserverValueForkeyPath
,并检查捕获通知的路径是否与所需属性匹配。这里有一个更好的KVO观测可视化:好的。我误解了你的意思,因为我是KVC的新手。哦!这看起来很有希望!我将使用稍微不同的实现来测试它。每当属性发生更改时,调用的方法是-(void)observeValueForKeyPath:(NSString*)对象的键路径:(id)对象更改:(NSDictionary*)更改上下文:(void*)contextWow。这真是太棒了,非常适合我要找的东西。你能把这个方法添加到你的答案中吗?KVO听起来不错,但是。夸张地说,你为我的世界打开了另一个很棒的博客!非常感谢。你看起来也很面熟,要么你曾经帮助过我,要么你曾经帮助过我。
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
- (id)init
{
    if(self = [super init])
    {
        unsigned int propertyCount;
        objc_property_t *properties = class_copyPropertyList([self class], &propertyCount);
        for(int i = 0; i < propertyCount; i++)[self addObserver:self forKeyPath:[NSString stringWithCString:property_getName(properties[i]) encoding:NSUTF8StringEncoding] options:NSKeyValueObservingOptionNew context:nil];
    }
    return self;
}

- (void)dealloc
{
    unsigned int propertyCount;
    objc_property_t *properties = class_copyPropertyList([self class], &propertyCount);
    for(int i = 0; i < propertyCount; i++)[self removeObserver:self forKeyPath:[NSString stringWithCString:property_getName(properties[i]) encoding:NSUTF8StringEncoding]];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"Changed value at key path: %@", keyPath);
}