Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.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
Objective c 通知观察者-开始使用绑定_Objective C_Cocoa_Binding_Cocoa Bindings - Fatal编程技术网

Objective c 通知观察者-开始使用绑定

Objective c 通知观察者-开始使用绑定,objective-c,cocoa,binding,cocoa-bindings,Objective C,Cocoa,Binding,Cocoa Bindings,为了开始使用绑定,我正在编写一个小应用程序,它可以将摄氏温度转换为开尔文温度,反之亦然 我有两个NSTEXT字段,它们绑定到两个属性,即浮点开尔文和浮点摄氏度。当然,我有两个自定义设置器,它们可以适当地设置每个属性的值 摄氏度的设定值为: centigrade = value; [self willChangeValueForKey:@"kelvin"]; kelvin = value + 273; [self didChangeValueForKey:@"kelvin"]; 我需要使用wil

为了开始使用绑定,我正在编写一个小应用程序,它可以将摄氏温度转换为开尔文温度,反之亦然

我有两个NSTEXT字段,它们绑定到两个属性,即
浮点开尔文
浮点摄氏度
。当然,我有两个自定义设置器,它们可以适当地设置每个属性的值

摄氏度的设定值为:

centigrade = value;
[self willChangeValueForKey:@"kelvin"];
kelvin = value + 273;
[self didChangeValueForKey:@"kelvin"];
我需要使用
willChangeValueForKey:
否则该值不会在其他NSTextField中更新

我的问题是,有没有一种更优雅的方式来做到这一点?如果我添加另一个属性和文本字段来将温度转换为华氏温度,我还需要在该getter中添加
willChange…
didChange…

有没有一种方法可以告诉nib文件这两个属性是链接的,当其中一个属性发生更改时,它必须通知两个观察者

编辑:

为了它的价值,我试着从centrigrade的二传手里面给开尔文的二传手打电话。但是如果我在凯尔文的二传中也这样做,会不会造成问题呢?例如:

centigrade = value;
[self setKelvin:value];


不要在此处使用willChangeValueForKey:/didChangeValueForKey:,通知是自动的。如果您没有看到通知,则表示您没有在中使用属性。您根本不需要自定义设置器

如果已明确禁用这些属性的自动kvo,则只应调用willChangeValueForKey:/didChangeValueForKey:

一旦你完成了这项工作,你就可以解决你的另一个问题。是的,两个属性都可以有一个属性更改触发通知,但是正如您所看到的,如果第二个属性更改也再次触发第一个属性,那么这是没有用的,依此类推

问题是您的模型不够复杂,无法处理您的问题。暂时忘记绑定,完全忘记演示文稿,直到模型正常工作。在伪代码中,忽略浮点细节,您至少需要实现以下功能:-

model.celcius = 100.0;
assert( model.kelvin == 373.0 )

model.kelvin = 0.0;
assert( model.celcius == -273.0 )
假设您遵循有关kvo Compliance的指南(并了解何时使用和何时不使用-即,您可以控制何时触发通知),那么您将能够连接textfield绑定,一切都将正常工作

这可能看起来像:-

@property (assign) float *temperatureKelvin;    // only one instance variable needed

- (float)temperatureFahrenheit {
  return tempeatureKelvin * ...;                // whatever formula is
}

- (float)temperatureCelcius {
  return tempeatureKelvin * ...;                // whatever formula is
}

- (void)setTemperatureFahrenheit:(float)val {
  self.temperatureKelvin = val * ...;           // whatever formula is
}

- (void)setTemperatureCelcius:(float)val { {
  self.temperatureKelvin = val * ...;           // whatever formula is
}
执行此操作的关键是确保更新temperatureKelvin的值时会发送一个通知,说明TemperatureHarenheit和TemperatureCelvius已更改。您可以通过将他们注册为受抚养人的财产来实现这一点

+ (NSSet *)keyPathsForValuesAffectingTemperatureFahrenheit {
    return [NSSet setWithObject:@"tempeatureKelvin"];
}

+ (NSSet *)keyPathsForValuesAffectingTemperatureCelcius {
    return [NSSet setWithObject:@"tempeatureKelvin"];
}

我觉得我完全偏离了轨道。我猜我需要使我的KVO模型兼容,而仅仅拥有两个浮点属性并不能解决这个问题?此外,您声明我根本不需要自定义设置程序-我不需要一些代码来将开尔文转换为摄氏度,反之亦然吗?我还只是覆盖了+keypathsforvaluesafectingvalueforkey,这似乎也很有效。但我还是很喜欢你所说的模型。FWIW,我确实有一个基本模型,但是如果我删除自定义访问器,它显然不会改变温度,但会改变值,但是合成的setter/getter仍然会被调用,并且值会被更新。我已经通过将两个文本字段连接到同一属性并更改其中一个更新另一个来确认了这一点。我添加了更多的解释。关于模型的要点并不是你真的需要一个复杂的模型,而是独立于你的视图开发它是很好的,最好是使用单元测试:)啊,所以关键是动态转换值,而不是存储它们!非常感谢你。这太棒了。但是,上述“keyPathsForValues…”代码仅在更改密钥开尔文时更新。当摄氏度改变时,它不会做任何事情。所以,为了做到这一点,我必须包含另一个集合,它在温度发生变化时发出通知。我想这是正确的方法?对于影响其他键的每个键,我需要通过keyPathsForValues通知Cocoa。。。方法。抱歉,我的错误-KeyPathForvaluesFectingValueForkey:出错-我现在就更正它
+ (NSSet *)keyPathsForValuesAffectingTemperatureFahrenheit {
    return [NSSet setWithObject:@"tempeatureKelvin"];
}

+ (NSSet *)keyPathsForValuesAffectingTemperatureCelcius {
    return [NSSet setWithObject:@"tempeatureKelvin"];
}