gpt4 book ai didi

objective-c - 如果不删除其他对象的观察者,KVO 会导致循环

转载 作者:行者123 更新时间:2023-12-03 16:54:46 26 4
gpt4 key购买 nike

我将观察者添加到多个 NSTextField 中以监视每个文本字段中的更改。每个文本字段的键在 Interface Builder 中的Bindings -> Value -> Model Key Path 处配置。当一个文本字段中的数字发生更改时,其他文本字段会自动更新其值。由于每个文本字段中都添加了一个观察者,因此我必须删除其他观察者以避免出现导致应用程序崩溃的循环。删除观察者后,我必须将它们添加回其他文本字段,以便可以监视用户的输入。我的方法运行良好,但我可以看到,如果添加大量观察者,这会变得很麻烦。

有没有办法简化这个过程,让我不必根据用户的输入添加和删除观察者?

#import "Converter.h"

@interface Converter ()

@property double kilometer, mile, foot;

@end

@implementation Converter

- (void)awakeFromNib {
[self addObserver:self forKeyPath:@"kilometer" options:0 context:nil];
[self addObserver:self forKeyPath:@"mile" options:0 context:nil];
[self addObserver:self forKeyPath:@"foot" options:0 context:nil];
}

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

if ([keyPath isEqualToString:@"kilometer"]) {
[self removeObserver:self forKeyPath:@"mile"];
[self removeObserver:self forKeyPath:@"foot"];

NSLog(@"kilometers");

[self setMile: [self kilometer] * 0.62137119 ];
[self setFoot: [self kilometer] * 3280.8399 ];

[self addObserver:self forKeyPath:@"mile" options:0 context:nil];
[self addObserver:self forKeyPath:@"foot" options:0 context:nil];
}

if ([keyPath isEqualToString:@"mile"]) {
[self removeObserver:self forKeyPath:@"kilometer"];
[self removeObserver:self forKeyPath:@"foot"];

NSLog(@"miles");

[self setKilometer: [self mile] * 1.609344 ];
[self setFoot: [self mile] * 5280 ];

[self addObserver:self forKeyPath:@"kilometer" options:0 context:nil];
[self addObserver:self forKeyPath:@"foot" options:0 context:nil];
}

if ([keyPath isEqualToString:@"foot"]) {
[self removeObserver:self forKeyPath:@"kilometer"];
[self removeObserver:self forKeyPath:@"mile"];

NSLog(@"feet");

[self setKilometer: [self foot] * 0.0003048 ];
[self setMile: [self foot] * 0.00018939394 ];

[self addObserver:self forKeyPath:@"kilometer" options:0 context:nil];
[self addObserver:self forKeyPath:@"mile" options:0 context:nil];
}
}

@end

这是用户界面的屏幕截图: unit converter screen shot

帮助阐明代码正在做什么(或假设正在做什么):

用户想要将英尺转换为公里和英里,因此他在英尺文本字段中输入一个值。使用适当的转换系数。

用户想要将公里转换为英里和英尺,因此他在公里字段中输入一个值。使用一组不同的转换系数。

等等...

最佳答案

通过自定义您的 setter 方法并实现 + (BOOL)automaticallyNotizesObserversForKey:,您可以以嵌套方式手动更新这些属性的通知。

以下代码经过测试可以正常工作。 (请注意,我没有使用您的系数和属性名称)。

#define BEGIN_UPDATE [self willChangeValueForKey:@"m"];\
[self willChangeValueForKey:@"km"];\
[self willChangeValueForKey:@"f"];

#define END_UPDATE [self didChangeValueForKey:@"f"];\
[self didChangeValueForKey:@"km"];\
[self didChangeValueForKey:@"m"];

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {
if ([key isEqualToString:@"f"]||[key isEqualToString:@"km"]||[key isEqualToString:@"m"]) {
return NO;
}
return [super automaticallyNotifiesObserversForKey:key];
}

- (void)setF:(float)f {
BEGIN_UPDATE
_m = 0.5*f;
_km = 0.1*f;
_f = f;
END_UPDATE
}

- (void)setKm:(float)km {
BEGIN_UPDATE
_km = km;
_f = 10*km;
_m = 5*km;
END_UPDATE
}

- (void)setM:(float)m {
BEGIN_UPDATE
_m = m;
_km = 0.2*m;
_f = 2*m;
END_UPDATE
}

关于objective-c - 如果不删除其他对象的观察者,KVO 会导致循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14484053/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com