为什么在另一个线程运行时NSTimer被阻止?

时间:2011-03-11 14:36:57

标签: iphone multithreading nstimer asihttprequest

我正试图在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),因此操作系统应该有足够的时间来切换线程。这在模拟器和实际设备上都会发生。

2 个答案:

答案 0 :(得分:6)

根据ASIHTTPRequest

  

对于更复杂的情况,或者你想在后台解析响应的地方,为每种类型的请求创建一个ASIHTTPRequest的最小子类,并覆盖requestFinished:和failWithProblem:。

否则,如果您使用默认回调,它们将在主线程上运行。

答案 1 :(得分:1)

NSTimer在同一个线程上运行 它在主线程上调用事件方法。

你的longyMethod方法可能会使用主踏板来做一些操作 在这个主线程块之前有2个滴答 检查一下!