2011-10-17 7 views
0

내 앱에서 충돌이 발생했습니다. 로그를 확인하고 ATOS를 사용할 때, 내가 실행하는 내 NSRunLoop에게 어디 인 충돌을 얻을 정확히 말해되지 않습니다 :iOS : NSThread에서 타이머를 실행하면 EXC_BAD_ACCESS가 발생합니까?

/** 
* Create a new thread for the timer 
* 
* @version $Revision: 0.1 
*/ 
- (void)createTimerThread { 
    NSThread *timerThread = [[NSThread alloc] initWithTarget:self selector:@selector(startTimerThread) object:nil]; 
    [timerThread start]; 
    [timerThread release]; 
}//end 


/** 
* Start the actual timer 
* 
* @version $Revision: 0.1 
*/ 
- (void)startTimerThread { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; 

    // Start timer 
    self.countTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateCounter:) userInfo:nil repeats:YES]; 

    [runLoop run];// <--- Crash happened here 
    [pool release]; 

}//end 


/** 
* Update the counter 
* 
* @version $Revision: 0.1 
*/ 
- (void)updateCounter:(NSTimer *)theTimer { 

    // Does tons of timer stuff here 

}//end 

당신이 볼 수 있듯이, 충돌이 [runLoop run]에서 발생하지만 난 더이 왜 그런지. 일반적으로 두 번째로 createTimerThread 메소드를 호출합니다.

내가 뭘 잘못하고 있니? 내가 원하는 것은 배경에서 타이머를 실행하여 UILabel을 업데이트해야하기 때문에 주 스레드에 없었기 때문입니다.

Grand Central Dispatch (GCD)와 같은 새로운 것을 사용해야합니까?

+0

NSZombies를 활성화하면 이유를 찾을 수 있습니다. EXC_BAD_ACCESS는 출시되는 무언가와 관련이 있습니다. 이는 a.k.a 좀비가 느슨해져서는 안됩니다. –

+0

백그라운드 스레드에서 UILabel에 액세스하고 있습니까? 아니면 다른 UI 요소입니까? – JustSid

+0

updateCounter 메서드에서 UILable을 업데이트합니다. 그래서, 그것이 현재 백그라운드에 있는지 확실하지 않습니다. –

답변

1

당신은 updateCounter가 UILabel을 업데이트 중이며 백그라운드 스레드에서 실행중인 타이머에서 호출되고 있다고하셨습니다. 그렇게 할 수 없으면 메인 스레드에서 UI보기를 업데이트해야합니다.

performSelectorOnMainThread 또는 GCD (기본 대기열로 발송)를 사용할 수 있습니다. mrwalker

에서 게시물

iOS4 Create Background Timer

봐 :이 SO 문서는 특히 GCD와 BG 타이머의 예를 가지고

GCD, Threads, Program Flow and UI Updating

: 나는 SO 게시물이에 모두 사용하여 샘플을 비교

+0

감사합니다. performSelectorOnMainThread에 의해 호출되는 다른 메서드로 UILabel을 업데이트했습니다. –

0

UI가 관련된 모든 호출은 이 아니며이 아니므로 기본 스레드에서 업데이트해야합니다.

실제 달성하려는 내용이 확실하지 않습니다. 당신이 모든 타이머 "tick"에 대해 계산적으로 비싼 것을한다면, GCD는 블록을 이용하는 것이 가장 좋습니다.

아마 당신은 우리에게 당신이하는 각각의 진드기에 대해 통찰력을 줄 수 있을까요?

+0

이것은 0부터 세는 단순한 타이머입니다. 얼마나 많은 시간이 경과했는지 보여주기 위해 UILabel을 업데이트합니다. 카운터는 새로운 코어 데이터 레코드가 생성 될 때마다 생성됩니다. –

+0

그래서 각 핵심 데이터 엔티티 인스턴스에는 자체 타이머가 있습니까? 아마도 더 나은 방법은 각 엔티티 인스턴스에 "startTime"임시 속성을 설정하는 것입니다. 그런 다음 각 엔티티를 통과하는 단일 타이머를 설정하고 경과 시간을 계산하고 UILabel을 업데이트하십시오. – cocoahero