在每个房产变更做一些事情

时间:2015-05-13 06:05:35

标签: ios objective-c properties

我的课程中有几个属性,我想在每次更改属性时调用saveToFile

我不想覆盖每个属性的setter。我应该覆盖 -[NSObject methodForSelector]?什么是最好的方式?

3 个答案:

答案 0 :(得分:6)

您可以注册为要监视的属性的观察者。 Cocoa's KVO功能可以帮助您。

基本上你需要调用addObserver:forKeyPath:options:context:并注册以在属性发生变化时得到通知。发生这种情况时,运行时会在注册为observer的对象上调用observeValueForKeyPath:ofObject:change:context:方法。你可以在这里做你想要的保存。

注册示例:

for(NSString *propName in self.propsIWantMonitored) {
    [self addObserver:self forKeyPath:propName change:0 context:@selector(saveToFile)];
}

并且用于处理道具值的变化:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

    // make sure we don't interfere with other observed props
    // and check the context param
    if (context == @selector(saveToFile)) {
        [self saveToFile];
    }
}

并取消注册:

for(NSString *propName in self.propsIWantMonitored) {
    [self removeObserver:self forKeyPath:propName context:@selector(saveToFile)];
}

上面的代码示例假设您已声明要监视的属性数组,您用它来注册为观察者。您使用context参数来确定是否将observeValueForKeyPath作为对您刚刚注册的观察者的响应进行调用,以免与您班级其他部分的其他KVO注册发生冲突

替代(以及更节能)解决问题的方法

上述方法有一点需要注意:如果连续设置了多个属性,那么saveToFile方法将在短时间内被多次调用,这可能会导致性能瓶颈并增加申请的能源使用情况。

另一种方法是在dirty中设置observeValueForKeyPath:标记并在saveToFile中重置。您可以saveToFile检查标志,如果对象不脏,则不要使用文件系统。

您可以安排定期调用saveToFile的计时器,这样一次设置多个属性只会导致一次磁盘访问。当您想要立即保存时,您可以随时手动拨打saveToFile

请注意。通过计时器,我指的是GCD timer,因为NSTimer也会对您的应用产生负面能量影响。

答案 1 :(得分:4)

您想要的是Key-Value-Observing或KVO。 例如,您注册了一个在每次属性更改时调用的方法。

如果您有一个文本字段,并且想要收听其文本的更改,则可以像这样注册

[self.textField addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:nil];

在课堂上你将实现这个方法:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

    if ([keyPath isEqualToString:@"text"]) {

        NSLog(@"Textfield changed - MAKE CHANGES HERE");
    }

}

如果您不熟悉KVO,这里有一个很好的教程: http://www.appcoda.com/understanding-key-value-observing-coding/

答案 2 :(得分:-1)

阅读物业观察员。 Swift中的一个例子:

var currentSession: Session? {
    didSet {
        if let session = self.currentSession {
            // Write session to file.
        }
    }
}

对于Objective-C,key-value observing可能更合适。