2010-11-11 55 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