假设您有一个类似于 NSSlider 的自定义控件,但支持选择一系列值,而不是单个值。属性的明显选择是 minValue、maxValue、leftValue、rightValue,或者你想命名它们。
您可能还想确保 leftValue 和 rightValue 始终位于 minValue 和 maxValue 之间。minValue 和 maxValue 相同。您不希望它们潜在地使现有的 leftValue 和 rightValue 无效,例如通过将 maxValue 设置为低于当前 rightValue 的值。
到目前为止非常直截了当。
但是,在确保适当的 KVO 可访问性/合规性的情况下,您会怎么做?您根本无法确保 KVO 以正确的顺序设置属性(即首先设置最小和最大限制,然后设置其他值)。
我碰巧有这样一个 UI 元素,如果不打开错误设置值的大门,我根本无法弄清楚要让它运行起来。
自定义控件旨在绑定到模型对象。如果我现在使用值创建这样的模型(最小值:0.00 最大值:42.00 左侧:14.00 右侧:28.00)我最终在自定义控件中进行以下设置(最小值:0.00 最大值:42.00 左侧:1.00 右侧:1.00)
这样做的原因是,它不是先调用 minValue 和 maxValue,而是先调用 leftValue 和 rightValue,这导致两个值都以 1.0(这是默认的 maxValue)结束。(然后将 maxValue设置为适当的值。)
//[self prepare] gets called by both, [self initWithCoder:] and [self initWithFrame:]
- (void)prepare
{
minValue = 0.0;
maxValue = 1.0;
leftValue = 0.0;
rightValue = 1.0;
}
- (void)setMinValue:(double)aMinValue
{
if (aMinValue < maxValue && aMinValue < leftValue) {
minValue = aMinValue;
[self propagateValue:[NSNumber numberWithDouble:minValue] forBinding:@"minValue"];
[self setNeedsDisplay:YES];
}
}
- (void)setMaxValue:(double)aMaxValue
{
if (aMaxValue > minValue && aMaxValue > rightValue) {
maxValue = aMaxValue;
[self propagateValue:[NSNumber numberWithDouble:maxValue] forBinding:@"maxValue"];
[self setNeedsDisplay:YES];
}
}
- (void)setLeftValue:(double)aLeftValue
{
double newValue = leftValue;
if (aLeftValue < minValue) {
newValue = minValue;
} else if (aLeftValue > rightValue) {
newValue = rightValue;
} else {
newValue = aLeftValue;
}
if (newValue != leftValue) {
leftValue = newValue;
[self propagateValue:[NSNumber numberWithDouble:leftValue] forBinding:@"leftValue"];
[self setNeedsDisplay:YES];
}
}
- (void)setRightValue:(double)aRightValue
{
double newValue = leftValue;
if (aRightValue > maxValue) {
newValue = maxValue;
} else if (aRightValue < leftValue) {
newValue = leftValue;
} else {
newValue = aRightValue;
}
if (newValue != rightValue) {
rightValue = newValue;
[self propagateValue:[NSNumber numberWithDouble:rightValue] forBinding:@"rightValue"];
[self setNeedsDisplay:YES];
}
当你希望 Apple 开放 Cocoa 的来源时,正是在这种时候。或者至少是一些用于更深入检查的控件。
您将如何实施这样的控制?
或更笼统地说:在遵守 KVO 的同时实现具有交叉依赖属性的类的最佳实践是什么?