2011-03-11 99 views
3

我想在iPhone上的背景下運行一個任務。我從performSelectorInBackground開始。我還在主線程上創建NSTimer,以檢查是否正常工作。我預計,而另一個線程做這件事的計時器將運行:爲什麼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),所以OS應該有足夠的時間來切換線程。這發生在模擬器和實際設備上。

+0

確保longyMethod不會對UI進行任何調用,並檢查您是否使用ASIHTTPRequest的異步方法。 – David 2011-03-11 14:48:33

+0

@Johny Grass:ASIHTTPRequest確實是異步的。但是,這很重要,它已經在後臺線程中運行了。 – 2011-03-11 15:25:17

+0

我敢打賭,有'ASIHTTPRequest'完成處理程序正在發生。看起來他們阻止了計時器。咦?奇怪的。 – 2011-03-11 15:40:10

回答

6

根據ASIHTTPRequest

對於更復雜的情況,還是要分析在後臺的響應,請ASIHTTPRequest的最小的子類,每種類型的請求,並覆蓋requestFinished:和failWithProblem: 。

否則,如果您使用默認回調,它們將在主線程上運行。

+1

是的確是這個問題。完全出乎意料,但至少有文件證明。 – 2011-03-12 14:05:07

1

NSTimer在同一個線程上運行。
它調用主線程上的事件方法。

您的longyMethod方法可能使用主要步驟來執行一些操作。
此主線程塊之前有2個刻度。
檢查它!

+0

請注意,我正在使用'performSelectorInBackground'開始lenghtyMethod。所以你說的是,performSelectorInBackground不會導致方法在後臺運行?這是沒有意義的。 – 2011-03-11 15:19:05

+0

好的,對不起,我沒有注意到這一點!我想快速閱讀...但爲什麼在長時間治療之前,這個計時器是2個計時器? – 2011-03-11 15:47:02

+0

我想我開始到達根目錄,如果它看起來像來自ASIHTTPRequest *的回調(「requestComplete:」),即使請求本身在另一個線程上運行,它總是在主線程上運行。意外的行爲。 – 2011-03-11 17:18:07

相關問題