【问题标题】:iOS4 Create Background TimeriOS4 创建后台定时器
【发布时间】:2010-11-11 12:22:21
【问题描述】:

我(基本上)需要在 iOS 4 上创建一个后台计时器,它允许我在经过特定时间后执行一些代码。我已经读到您可以使用一些[NSThread detachNewThreadSelector: toTarget: withObject:]; 来完成此操作,但在实践中它是如何工作的?如何确保线程也保留在后台。本地通知对我有用,因为我需要执行代码,而不是通知用户。

我们将不胜感激!

【问题讨论】:

    标签: objective-c ios4 localnotification background-thread


    【解决方案1】:

    您也可以使用 Grand Central Dispatch (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];
        });
    }); 
    

    Grand Central Dispatch (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:

    【讨论】:

    • 但是这个 dispatch_after 在后台不起作用。要检查相同的内容,请将代码放入 applicationDidEnterBackground: 方法中,然后查看是否调用了您的块。
    • 非常好的建议这个后台任务。我会尝试更频繁地记住它。
    【解决方案2】:

    您可以使用这些调用在新线程 (detachNewThred) 中执行带有某些参数 (withObject) 的对象 (toTarget) 的方法(选择器)。

    现在,如果您想执行延迟任务,最好的方法是performSelector: withObject: afterDelay:,如果您想在后台运行任务,请调用detachNewThreadSelector: toTarget: withObject:

    【讨论】:

    • beast 方法 :) 好的,所以如果我用 detachNewThreadSelector: toTarget: withObject: 创建一个线程,它会留在后台吗?
    • jajaja,对“野兽”方法感到抱歉 =/ 是的,它将与主线程并行执行,请查看 NSObject 中的 performSelector 方法以获取完整的可能性列表。跨度>
    • 太棒了,非常感谢,我一直在拔头发! :)
    【解决方案3】:

    这些建议的方法是否仅在应用程序首先启用后台执行(使用 UIBackgroundMode)时才适用?

    我假设如果一个应用程序不能合法地声称是一个 voip/音乐/位置感知应用程序,那么如果它实现了这里描述的内容,那么它不会在时间间隔到期时执行?

    【讨论】:

    • 不,这不正确,但是,应用程序仍然运行的可能性很小,具体取决于您设置的时间。当你有一个 voip / 音乐 / 位置应用程序时,操作系统通常会尽量保持它运行,而不是停止进程以释放资源。
    猜你喜欢
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    相关资源
    最近更新 更多