我试图在类(StopWatch)中观察一个int属性(totalSeconds),其中每次触发时间(一秒间隔)时总秒数加1我的自定义类(DynamicLabel)是UILabel的子类每次totalSeconds改变时都应该收到一个observeValueForKeyPath消息但是从不调用它。以下是相关代码:
#import "StopWatch.h"
@interface StopWatch ()
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation StopWatch
@synthesize timer;
@synthesize totalSeconds;
- (id)init
{
self = [super init];
if (self) {
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(fireAction:) userInfo:nil repeats:YES];
[runLoop addTimer:timer forMode:NSRunLoopCommonModes];
[runLoop addTimer:timer forMode:UITrackingRunLoopMode];
}
return self;
}
- (void)fireAction:(NSTimer *)aTimer
{
totalSeconds++;
}
@end
#import "DynamicLabel.h"
@implementation DynamicLabel
@synthesize seconds;
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
seconds ++;
[self setText:[NSString stringWithFormat:@"%i",seconds]];
}
@end
并在视图控制器中:
- (void)viewDidLoad
{
[super viewDidLoad];
watch = [[StopWatch alloc] init];
[watch addObserver:dLabel1 forKeyPath:@"totalSeconds" options:NSKeyValueObservingOptionNew context:NULL];
}
其中dLabel是DynamicLabel的一个实例
有人知道为什么会这样吗?它肯定与NSTimer有关,因为我尝试了同样的事情,我手动更改totalSeconds的值以检查KVO是否正常工作,并且工作正常。但是,当在计时器的fire方法中totalSeconds增加时,thinkValueForKeyPath方法永远不会被调用。此外,对于那些想知道我为什么使用KVO的人来说,这是因为在真实的应用程序中(这只是一个测试应用程序),我需要在屏幕上显示多个正在运行的秒表(在不同的时间)并记录已过去的倍。我想用一个时钟做这个。我非常感谢能得到的任何帮助。
谢谢,
答案 0 :(得分:4)
键值观察仅适用于属性。您的计时器没有使用您的属性访问器来增加值;它正在直接改变ivar,不会产生任何KVO事件。将其更改为self.totalSeconds++
,它应该有效。