我有一個功能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];
}
我用線[self performSelector:@selector(quitAnimationThread) onThread:m_animationthread withObject:nil waitUntilDone:NO]
,而不是簡單地設置m_animationthreadrunning = NO
在stopAnimating
是因爲運行的循環可能不會返回的原因: