2010-11-11 63 views
3

我(基本上)需要在iOS 4上創建一個後臺計時器,這將允許我在特定的時間量過去時執行一些代碼。我讀過,你可以使用一些[NSThread detachNewThreadSelector: toTarget: withObject:];來完成這個工作,但是這在實踐中是如何工作的?我怎樣才能確保線程仍然在後臺。本地通知將不是爲我工作,因爲我需要執行代碼,不通知用戶。iOS4創建後臺計時器

幫助,將不勝感激!

回答

4

您可以使用這些調用在新線程(detachNewThred)中執行帶有某個參數(withObject)的對象(toTarget)的方法(選擇器)。

現在,如果要執行延遲的任務可能是最好的辦法是performSelector: withObject: afterDelay:而如果你想運行在後臺任務調用detachNewThreadSelector: toTarget: withObject:

+0

「野獸」的方法:)好吧,如果我用'detachNewThreadSelector:toTarget:withObject:'將它留在後臺? – 2010-11-11 12:54:17

+0

jajaja,對於「野獸」方法感到抱歉= /是它會與主線程並行執行,請查看NSObject中的performSelector方法以獲取完整的可能性列表。 – 2010-11-11 13:08:10

+0

非常好的人,非常感謝,我一直把我的頭髮拉出來! :) – 2010-11-11 13:10:53

20

你也可以做到這一點使用大中央調度(GCD) 。這樣,您可以使用塊將代碼保存在一個位置,並且如果您在完成後臺處理後需要更新UI,請確保再次調用主線程。這裏有一個簡單的例子:

#import <dispatch/dispatch.h> 

… 

NSTimeInterval delay_in_seconds = 3.0; 
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, delay_in_seconds * NSEC_PER_SEC); 
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 

UIImageView *imageView = tableViewCell.imageView; 

// ensure the app stays awake long enough to complete the task when switching apps 
UIBackgroundTaskIdentifier taskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:{}]; 

dispatch_after(delay, queue, ^{ 
    // perform your background tasks here. It's a block, so variables available in the calling method can be referenced here.   
    UIImage *image = [self drawComplicatedImage];   
    // now dispatch a new block on the main thread, to update our UI 
    dispatch_async(dispatch_get_main_queue(), ^{   
     imageView.image = image; 
     [[UIApplication sharedApplication] endBackgroundTask:taskIdentifier]; 
    }); 
}); 

大中央調度(GCD)參考: http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html

塊參考: http://developer.apple.com/library/ios/#featuredarticles/Short_Practical_Guide_Blocks/index.html%23//apple_ref/doc/uid/TP40009758

後臺任務參考: http://developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/beginBackgroundTaskWithExpirationHandler

+0

+1爲塊和GCD新的熱點。 – Kongress 2011-06-03 14:30:27

+1

但是這個dispatch_after在後臺不起作用。檢查相同的代碼在applicationDidEnterBackground:方法中,看看你的塊是否被調用。 – 2012-05-23 06:44:33

+1

好點 - 我已經添加了一個背景任務到我的答案。 – mrwalker 2012-05-23 08:10:03

0

難道這些建議的方法僅適用於啓用了後臺執行的應用程序(使用UIBackgroundM敖德)在第一個地方?

我認爲,如果一個應用程序不能合法地聲稱是一個VoIP /音樂/位置感知應用程序,那麼如果它實現了這裏描述的內容,它將不會在時間間隔到期時執行?

+0

不,這是不正確的,但是,應用程序仍然運行的機會很渺茫,這取決於您設置的時間。當你有一個voip /音樂/位置的應用程序,操作系統通常會試圖保持它的運行,而不是停止進程來釋放資源。 – 2011-12-06 12:30:08