我对如何在线程中使用NSRunLoop有一些疑问。在Apple的线程编程指南中,它提到“你的代码提供了用于实现运行循环的实际循环部分的控制语句 - 换句话说,你的代码提供了驱动运行循环的while或for循环。”因此,当使用NSURLConnection在新线程中异步加载数据时,我编写以下代码并且它可以工作:
...
....
NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[NSThread detachNewThreadSelector:@selector(downloadThread:) toTarget:self withObject:nil];
....
...
选择器“downloadThread”是新线程的入口点,以下是“downloadThread”代码:
- (int) downloadThread:(id)option {
BOOL ret;
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[connection start];
while (finished == NO) {
ret = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
return 1;
}
这里有一个问题,NSRunLoop是一个循环,为什么我们应该使用循环语句“while(finish == NO)”来控制NSRunLoop?尽管苹果的文档提到了这一点,但我只是不明白。另一方面,当使用计时器时,我们不需要循环语句来控制NSRunLoop,它可以工作,就像这样:
...
....
NSTimer* _timer = [NSTimer timerWithTimeInterval:1 target:object selector:@selector(timerFunc) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
[_timer fire];
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
....
...
那么,在什么情况下我们应该使用循环语句来控制NSRunLoop?
答案 0 :(得分:0)
阅读-[NSRunLoop runMode:beforeDate:]
的{{3}}。该方法在处理单个输入源后返回。因此,如果您希望继续处理输入源,直到某个特定事件发生,您必须循环它。
我不确定定时器代码来自何处,但无法保证调用-runMode:beforeDate:
一次将允许定时器触发。此外,-runMode:beforeDate:
不会因为计时器被触发而返回。所以,这个代码对我来说至少有两个错误。