나는 스레드 안전하고 게임 애니메이션의 짧은 기간 동안 그리기 기능을 drawView
있습니다. 기능이 startAnimating
이고 stopAnimating
입니다. 백그라운드 스레드가 drawView
을 일정한 속도로 호출하고 싶지만 애니메이션이 활성화 된 기간 동안에 만 호출하기를 원합니다.iOS에서 애니메이션 스레드를 설정하는 방법은 무엇입니까?
startAnimating
에서 나는 스레드의 실행을 위해보기의 performSelectorInBackground:withObject:
을 호출 할 것입니다.
스레드 통신을 수행하고 드로잉 스레드를 초기화하는 방법에 대해 약간 혼란 스럽습니다. 구체적으로 말하자면 디스플레이 링크 메시지를 수신하기 위해 runloop을 설정 한 다음 종료하고 실행을 종료해야한다고 스레드에 알립니다. 메인 스레드에서 stopAnimating
을 호출하면 깨끗하게 루프됩니다. drawView
이 stopAnimating
뒤에 절대 호출되지 않도록하고 드로잉 스레드가 드로잉 작업 도중에 갑자기 취소되지 않도록하고 싶습니다. 나는이 종류의 질문에 대해 매우 열악한 답을 많이 보았다.
// object members
NSThread *m_animationthread;
BOOL m_animationthreadrunning;
- (void)startAnimating
{
//called from UI thread
DEBUG_LOG(@"creating animation thread");
m_animationthread = [[NSThread alloc] initWithTarget:self selector:@selector(animationThread:) object:nil];
[m_animationthread start];
}
- (void)stopAnimating
{
// called from UI thread
DEBUG_LOG(@"quitting animationthread");
[self performSelector:@selector(quitAnimationThread) onThread:m_animationthread withObject:nil waitUntilDone:NO];
// wait until thread actually exits
while(![m_animationthread isFinished])
[NSThread sleepForTimeInterval:0.01];
DEBUG_LOG(@"thread exited");
[m_animationthread release];
m_animationthread = nil;
}
- (void)animationThread:(id)object
{
@autoreleasepool
{
DEBUG_LOG(@"animation thread started");
m_animationthreadrunning = YES;
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
CADisplayLink *displaylink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkAction:)];
[displaylink setFrameInterval:3];
[displaylink addToRunLoop:runLoop forMode:NSDefaultRunLoopMode];
while(m_animationthreadrunning)
{
[runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
DEBUG_LOG(@"runloop gap");
}
[displaylink removeFromRunLoop:runLoop forMode:NSDefaultRunLoopMode];
DEBUG_LOG(@"animation thread quit");
}
}
- (void)quitAnimationThread
{
DEBUG_LOG(@"quitanimationthread called");
m_animationthreadrunning = NO;
}
- (void)displayLinkAction:(CADisplayLink *)sender
{
DEBUG_LOG(@"display link called");
//[self drawView];
}
단순히 실행 루프는 반환하지 않을 수 있기 때문에 stopAnimating
에서 m_animationthreadrunning = NO
이 설정 [self performSelector:@selector(quitAnimationThread) onThread:m_animationthread withObject:nil waitUntilDone:NO]
아닌 줄을 사용하는 이유 :