2014-11-01 76 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,並且創建許多計時器效率不高。