Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/109.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 对每个属性更改都做些什么_Ios_Objective C_Properties - Fatal编程技术网

Ios 对每个属性更改都做些什么

Ios 对每个属性更改都做些什么,ios,objective-c,properties,Ios,Objective C,Properties,我的类中有几个属性,我想在每次属性更改时调用saveToFile 我不希望覆盖每个属性的setter。我应该重写吗 -[NSObject methodForSelector]?最好的方法是什么?仔细阅读物业观察员。Swift中的一个示例: var currentSession: Session? { didSet { if let session = self.currentSession { // Write session to file.

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

我不希望覆盖每个属性的setter。我应该重写吗
-[NSObject methodForSelector]
?最好的方法是什么?

仔细阅读物业观察员。Swift中的一个示例:

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

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

您想要的是所谓的键值观察或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,这里有一个不错的教程:

您可以注册为要监视的属性的观察者。功能将在这里帮助您

基本上,您需要调用
addObserver:forKeyPath:options:context:
,并注册以在属性更改时收到通知。当发生这种情况时,运行库对注册为观察者的对象调用
observeValueForKeyPath:ofObject:change:context:
方法。你可以在这里做你想做的储蓄

注册示例:

for(NSString *propName in self.propsIWantMonitored) {
    [self addObserver:self forKeyPath:propName change:0 context:@selector(saveToFile)];
}
for(NSString *propName in self.propsIWantMonitored) {
    [self removeObserver:self forKeyPath:propName 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 addObserver:self forKeyPath:propName change:0 context:@selector(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


注意。我指的是计时器,因为NSTimer对您的应用程序也有负面的能量影响。

请提供一些代码作为示例。这是给Objective-C的吗?请在标签上注明。