美文网首页
一个关于property的小问题

一个关于property的小问题

作者: 227f600b867c | 来源:发表于2017-03-02 17:26 被阅读12次

今天在群里看到一个问题,如何在类的每个property值发生变化时去执行同一个方法?看到他这么写

- (void)setAProperty:(NSString *)aProperty {
    _aProperty = aProperty;
    [self xxMethod];
}

- (void)setBProperty:(NSString *)bProperty {
    _bProperty = bProperty;
    [self xxMethod];
}

.
.
.

就这样十来个property的setter都重写了一遍。

我想是否可以通过重写setValueForKey方法来实现,发现在给property赋值时并不执行setValueForKey方法。所以添加一个方法

- (void)xxSetValue:(id)value forKey:(NSString *)key {
    [self setValue:value forKey:key];
    [self xxMethod];
}

但是,只能在赋值时这样调用才有效

 [xx xxSetValue:value forKey:aProperty];

无法通过直接赋值去触发。

后来想到可以通过runtime获取所有的property,然后遍历,给每个property都加kvo,在kvo监听方法里去调用[self xxMethod]。

通过runtime获取所有的property

- (NSArray *)getAllProperty {
    NSMutableArray *allProperties = [NSMutableArray array];
    unsigned int count;
    objc_property_t *properties = class_copyPropertyList([self class], &count);
    for (int i = 0; i < count; i++) {
        objc_property_t property = properties[i];
        const char *cName = property_getName(property);
        NSString *propertyName = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
        [allProperties addObject:propertyName];
    }
    return allProperties.copy;
}

添加kvo

- (void)addKVO {
    for (NSString *property in [self getAllProperties]) {
        [self addObserver:self forKeyPath:property options:NSKeyValueObservingOptionNew context:nil];
    }
}

kvo监听

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    [self xxMethod];
}

这样,在init的时候去调一下[self addKVO]就行了
最后记得在dealloc的时候removeObserver

- (void)dealloc {
    for (NSString *property in [self getAllProperties]) {
        [self removeObserver:self forKeyPath:property];
    }
}

这是我的拙见,如果有好方法再更新

相关文章

网友评论

      本文标题:一个关于property的小问题

      本文链接:https://www.haomeiwen.com/subject/uadkgttx.html