我正试图在iPhone的后台运行一个长时间的任务。我用performSelectorInBackground
开始。我还在主线程上创建一个NSTimer
,以检查是否有效。我期望计时器会在另一个线程执行时运行:
- (void)viewDidLoad
{
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
selector:@selector(onTimerEvent:)
userInfo:nil repeats:YES];
[self performSelectorInBackground:@selector(lengthyMethod) withObject:nil];
NSLog(@"Here we go!");
}
- (void)onTimerEvent:(NSTimer *)timer
{
NSLog(@"timer!");
}
lenghtyMethod
执行大量内容,包括使用 ASIHTTPRequest 等进行网址下载。
NSLog
的输出如下所示:
2011-03-11 15:17:07.470 MyApp[6613:207] Here we go!
2011-03-11 15:17:07.570 MyApp[6613:207] timer!
2011-03-11 15:17:07.670 MyApp[6613:207] timer!
// ... several seconds of output from lenghtyMethod omitted ...
2011-03-11 15:17:11.075 MyApp[6613:207] timer!
2011-03-11 15:17:11.170 MyApp[6613:207] timer!
// ... etc ... timer runs as expected when the call is completed ...
问题是后台线程似乎阻止了计时器。我对此的理解是performSelectorInBackground应该在与主循环分开的新线程中运行。
我不懂。当线程正在运行时,我没有从计时器输出。呼叫完成后,计时器再次开始记录。
对于记录,线程主要是进行I / O(加载URL),因此操作系统应该有足够的时间来切换线程。这在模拟器和实际设备上都会发生。
答案 0 :(得分:6)
对于更复杂的情况,或者你想在后台解析响应的地方,为每种类型的请求创建一个ASIHTTPRequest的最小子类,并覆盖requestFinished:和failWithProblem:。
否则,如果您使用默认回调,它们将在主线程上运行。
答案 1 :(得分:1)
NSTimer在同一个线程上运行 它在主线程上调用事件方法。
你的longyMethod方法可能会使用主踏板来做一些操作 在这个主线程块之前有2个滴答 检查一下!