2014-11-01 80 views
-1

我有一个计时器的某一个日期我今天部件倒计时。我从我的视图控制器收集日期,然后在扩展中启动计时器,然后从三个标签中显示日期,分别为小时,分钟和秒。在我的应用程序中......这是完美的,但在通知中心并非如此。倒计时加载正确并且效果很好,持续约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]]]; 

} 

谢谢!

回答

3

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

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

这意味着每次你调用这个方法的时候,它的调度另一个定时器来调用这个方法每秒(每秒因为repeats:YES)。这意味着,每一秒钟(由于计算机中的任何滞后都会产生一个微偏移量),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 

EW,我们可以代表这更好 - 我们可以!我们可以使用六西格玛符号,像这样:

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

但足够的数学。平均达到高达2,000,000定时器在20秒内初始化。这是定时器的很多,和小部件,最终艰难地追赶呼吸(没有更多的内存!)和死/崩溃/重新启动。

以下是如何解决这个问题: 如果你真的想这个方法循环本身,调用

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

的方法来代替。

你可以按照你现在这样做的方式来做,而不是做repeats:NO,但我不认为计时器会在1.0秒后自行创建invalidate,并且创建许多计时器效率不高。