好的,在整个晚上阅读了 Apple 页面后,我终于用这段代码解决了这个问题:
// 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
原因是因为运行循环可能不会及时返回,但调用选择器会强制它返回。