2012-05-29 32 views
6

我發起一個後臺任務這樣的:可以調用performSelectorOnMainThread:調用beginBackgroundTaskWithExpirationHandler並且應用程序在後臺之後嗎?

UIApplication* application = [UIApplication sharedApplication]; 
_backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^ 
          { 
           [application endBackgroundTask:_backgroundTask]; 
           _backgroundTask = UIBackgroundTaskInvalid; 
          }]; 

該應用程序發送到後臺,一切都剛剛好。

一段時間後,某些條件得到滿足,有的對象最終執行此代碼:

[self performSelectorOnMainThread:@selector(doSomething) withObject:nil waitUntilDone:YES]; 

在這一點上,應用程序崩潰!

請注意,在這種情況下,對象正在主線程中執行。

我取代了上面的代碼與此:

dispatch_async(dispatch_get_main_queue(), ^{ 
     [self doSomething]; 
    }); 

,一切似乎是好了,崩潰消失了。

我可以想象的是,waitUntilDone:YES可能是這裏的區別,但那只是我的直覺。

我的問題是:

是否允許使用performSelectorOnMainThread:withObject:waitUntilDone:是當應用程序在後臺運行?

如果是這樣,爲什麼應用程序崩潰以及爲什麼dispatch_async解決了問題?

在此先感謝!

+0

是'doSomething'實際上是否改變了用戶界面?它是否在做應用程序在後臺時有意義的工作?也許這種方法不應該在主(UI)線程後面運行呃所有,不管你是否看到崩潰。 – Nate

+0

doSomething沒有對UI做任何事情。它只是使用NSNotificationCenter發送通知,並且沒有人正在收聽該通知(我通過移除所有觀察者確定)。 – Lio

+0

你可以發佈崩潰日誌嗎? – viggio24

回答

1

使用performSelectorOnMainThread:withObject:waitUntilDone:YES可能是線程死鎖的原因。當前線程停止並等待。如果主線程沒有及時完成選擇器,iOS可以殺死您的應用程序以捆綁主線程的時間超過允許的時間(通常爲10秒,有時更少)。

dispatch_async(dispatch_get_main_queue .. 。呼叫不會以這種方式阻止,它總是在隊列中放置一個事件並等待輪到它,並且當前線程繼續運行而不會停止

沒有關於崩潰本質的更多信息,很難說出發生了什麼。

相關問題