2014-11-01 2 views
-1

오늘의 위젯에서 카운트 다운되는 타이머가 있습니다. 내 View Controller에서 날짜를 모으고 확장 프로그램에서 타이머를 시작하고 거기에서 날짜를 세 개의 레이블 인 Hours, Minutes, Seconds로 표시합니다. 내 응용 프로그램에서는 ... 완벽하지만 알림 센터에서는 그렇지 않습니다. 카운트 다운이 올바르게로드되고 약 20 초 동안 훌륭하게 작동합니다. 그 다음 초를 건너 뛰고 정지 한 다음 약 4 초 후에 다시 시작하고 전체 위젯을 다시 설정합니다 (모든 것이 사라짐). 약 2 초 후 전체 위젯이 재설정됩니다. 이것은 메모리 경고인가요?오늘 연장의 타이머 연장 연장이 동결 됨

보기 컨트롤러 : mainTextLabel.text = 436,496,400

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 개의 예정된 타이머가 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 

으으을, 우리는이 더 잘 표현할 수 있습니다! 우리는과 같이 시그마 표기법을 사용할 수 있습니다

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

그러나 충분한 수학. 그 평균은 무려 2,000,000 타이머가 20 초 후에 초기화됩니다. 그 타이머 타이머이며, 결국 위젯은 숨을 (더 이상 기억을 잡으려고 고투) 및 사망/충돌/자체를 다시 시작합니다.

는 여기를 해결하는 방법은 다음과 같습니다 당신이 정말로 루프 자체에이 방법을 원하는 경우, 대신 방법에

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

를 호출합니다.

당신은 현재 그걸 할 수 있고 repeats:NO을 대신 할 수 있습니다. 그러나 타이머가 012 초 동안 지나면 invalidate 그 자체가 아니며 많은 타이머를 생성하는 것이 그리 효율적이지 않을 것이라고 생각합니다.