计时器在今天扩展冻结扩展

时间:2014-11-01 04:20:09

标签: ios objective-c timer widget

我有一个计时器,可以在我今天的小部件中倒计时。我从View Controller收集日期,然后在扩展程序中启动计时器,然后从那里我以三个标签显示日期,小时,分钟和秒。在我的应用程序中...这是完美的,但在通知中心却不是这样。倒计时正确加载并且大约20秒工作。之后它会跳过一秒并冻结,然后它会在大约4秒内再次启动,然后它将重置整个小部件(一切都消失),然后大约2秒后整个小部件重置。这是记忆警告还是什么?

查看控制器:  mainTextLabel.text = 436496400

NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.nicmac.nextgame"];

        [sharedDefaults setObject:mainTextLabel.text forKey:@"MyNumberKey"];
        [sharedDefaults synchronize];

今日视图控制器

- (id)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(userDefaultsDidChange:)
                                                     name:NSUserDefaultsDidChangeNotification
                                                   object:nil];
    }
    return self;
}
- (void)viewDidLoad {
    [super viewDidLoad];

    self.preferredContentSize = CGSizeMake(320, 300);

    [self performSelector:@selector(updateNumberLabelText) withObject:nil afterDelay:1.0];


}

- (void)userDefaultsDidChange:(NSNotification *)notification {
    [self performSelector:@selector(updateNumberLabelText) withObject:nil afterDelay:1.0];

}

- (void)updateNumberLabelText {

    NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.nicmac.nextgame"];
    NSString *date = [defaults stringForKey:@"MyNumberKey"];
    self.numberLabel.text = [NSString stringWithFormat:@"%@", date];


    NSString *doubleString = self.numberLabel.text;
    double value = [doubleString doubleValue];

    destinationDate = [NSDate dateWithTimeIntervalSince1970:value];
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateNumberLabelText) userInfo:nil repeats:YES];

    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

    int units = NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;

    NSDateComponents *components = [calendar components:units fromDate:[NSDate date] toDate:destinationDate options:0];


    [hour setText:[NSString stringWithFormat:@"%ld", (long)[components day] * 24 + (long)[components hour]]];
    [minute setText:[NSString stringWithFormat:@"%ld", (long)[components minute]]];
    [second setText:[NSString stringWithFormat:@"%ld", (long)[components second]]];

}

谢谢!

1 个答案:

答案 0 :(得分:3)

这里的问题在于- (void)updateNumberLabelText方法。 具体来说,这里:

timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateNumberLabelText) userInfo:nil repeats:YES];

这意味着每次调用此方法时,它都会安排另一个计时器每秒调用此方法(因为repeats:YES而每秒调用一次)。这意味着,每秒(由于计算机中的任何延迟而具有微偏移),x个预定计时器正在产生x更多数量的预定计时器,这意味着每秒钟您的计时器数量增加一倍。这称为指数增长,可以建模为2^x

所以要在20秒内找到计时器的数量:

2^1+2^2+2^3+2^4+2^5+2^6+2^7+2^8+2^9+2^10+2^11+2^12+2^13+2^14+2^15+2^16+2^17+2^18+2^19+2^20

我们能否更好地代表这一点 - 我们可以!我们可以像这样使用sigma表示法:

 <no. of seconds>
Σ    2^i
 i=1

但足够的数学。平均在20秒内初始化的高达 2,000,000 计时器的平均值。这是一个很多的计时器,并且小部件最终会努力去呼吸(没有更多的内存!)并且死亡/崩溃/重启自己。

以下是修复方法: 如果你真的希望这个方法循环自己,请调用

[self performSelector:@selector(updateNumberLabelText) withObject:nil afterDelay:1.0];

在方法中。

您可以按照当前的方式执行此操作并执行repeats:NO,但我不认为计时器会在1.0秒之后自invalidate,并创建那么多计时器不是很有效率。

相关问题