我正在尝试理解RunLoops的概念。我已经阅读了苹果开发者指南中关于RunLoops的内容,并在某种程度上理解了RunLoops的概念。为了让我的概念更加清晰,我编写了一个非常简单的代码,其中使用了RunLoops。以下是代码:
- (void)viewDidLoad
{
[super viewDidLoad];
thread = [[NSThread alloc] initWithTarget:self selector:@selector(testMethod) object:nil];
[thread start];
}
- (void)testMethod {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSLog(@"Thread Entered");
NSMachPort* dummyPort = [[NSMachPort alloc] init];
[[NSRunLoop currentRunLoop] addPort:dummyPort forMode:NSDefaultRunLoopMode];
while(!exitThread) {
NSLog(@"Thread did some work");
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
[[NSRunLoop currentRunLoop]
removePort:dummyPort
forMode:NSDefaultRunLoopMode];
[dummyPort release];
NSLog(@"Thread Exited");
[pool drain];
}
- (IBAction)doDomeWorkOnBackgroundThread:(id)sender {
[self performSelector:@selector(dummyMethod) onThread:thread withObject:nil waitUntilDone:NO];
}
- (IBAction)exitThread:(id)sender {
[self performSelector:@selector(exitBackgroundThread) onThread:thread withObject:nil waitUntilDone:NO];
}
- (void)exitBackgroundThread {
exitThread = YES;
}
- (void)dummyMethod {
//Empty
}
在上面的代码中,我正在创建一个后台线程,并在该后台线程上调用函数
testMethod
。 在testmethod
内部,我运行了一个while循环,其中检查BOOL变量exitThread
并使用NSRunLoop的 -(BOOL)runMode:beforeDate:
方法来运行后台线程的RunLoop。 有两个IBAction连接到两个按钮。正如IBAction的名称所示,其中一个是exitThread
,另一个是唤醒线程并执行写在while循环中的NSLog语句。以上代码按照我的预期运行。每当执行
doDomeWorkOnBackgroundThread
方法时,线程从其runloop中醒来,执行while循环的下一次迭代,检查BOOL变量exitThread
,并在找到它的值为false时进入while循环并执行NSlog语句。同样,当执行exitThread:
方法时,将exitThread
变量设置为true,这将导致while循环和线程退出。但是,我需要更多的澄清:
1)如果在while循环中使用
run
或runUntilDate:
方法而不是runMode:beforeDate:
,则当执行exitThread:
方法时线程永远不会退出。在后台线程上调用exitBackgroundThread方法,但是当我使用runMode:beforeDate:
时,while循环不会执行其下一次迭代(就像它所做的那样),因此线程永远不会退出。2)我尝试将
exitBackgroundThread
方法更改为- (void)exitBackgroundThread {
exitThread = YES;
CFRunLoopStop(CFRunLoopGetCurrent());
}
由于
exitBackgroundThread
在后台线程上执行,因此CFRunLoopGetCurrent()应该给出后台线程的RunLoop。所以,这应该理想地停止后台线程的运行循环,无论我使用哪种NSRunLoop方法来启动RunLoop。因此,在任何情况下,调用上述函数时线程必须退出。但事实并非如此。我知道我在这里遗漏了一些东西,并且我正在进行大量的搜索以找到答案,但似乎找不到正确的答案。
**编辑
我发现这个问题与我的第一个查询非常相似。它在很大程度上解决了我的第一个疑问。