如何确保后台任务已成功结束

时间:2014-06-05 03:16:40

标签: ios xcode background task

我有一个关于后台任务让我困惑几天的问题。为了使描述简单,我将我的项目分成了这个实验。

#import "ViewController.h"

@interface ViewController () {
    UIBackgroundTaskIdentifier background;
    NSTimer *t;
}

- (void)beginBackgroundTask;
- (void)endBackgroundTask;
- (void)printIt;

- (IBAction)startBGTaskPressed:(id)sender;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

    t = nil;
    background = UIBackgroundTaskInvalid;

    [self beginBackgroundTask];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Internal use

- (void)beginBackgroundTask {
    NSLog(@"%s", __PRETTY_FUNCTION__);

    UIApplication *app = [UIApplication sharedApplication];
    background = [app beginBackgroundTaskWithExpirationHandler:^{
        NSLog(@"%s", __PRETTY_FUNCTION__);

        [self endBackgroundTask];
    }];

    NSLog(@"background created: %d", background);

    // Start the long-running task and return immediately.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        t = [NSTimer scheduledTimerWithTimeInterval:5.0
                                             target:self
                                           selector:@selector(printIt)
                                           userInfo:nil
                                            repeats:YES];

        [[NSRunLoop currentRunLoop] addTimer:t
                                     forMode:NSRunLoopCommonModes]; // NSDefaultRunLoopMode
        [[NSRunLoop currentRunLoop] run];
    });
}

- (void)endBackgroundTask {
    NSLog(@"Ending background: %d", background);

    if (t!=nil) {
        [t invalidate];
        t = nil;
    }

    [[UIApplication sharedApplication] endBackgroundTask:background];
    background = UIBackgroundTaskInvalid;
}

- (void)printIt {
    NSLog(@"%s", __PRETTY_FUNCTION__);
    NSLog(@"remaining: %f", [[UIApplication sharedApplication] backgroundTimeRemaining]);
}

#pragma mark - Actions

- (IBAction)startBGTaskPressed:(id)sender {
    if (background==UIBackgroundTaskInvalid) {
        NSLog(@"background not ready --> create");

        [self beginBackgroundTask];
    }
    else {
        NSLog(@"background ready --> return");
    }
}

@end

简短说明:在- (void)viewDidLoad中,我按- (void)beginBackgroundTask创建后台任务。当应用程序进入后台后,当后台任务过期(3分钟,但在某些文档中提到10分钟)时,会执行- (void)endBackgroundTask,其中清除计时器并结束后台任务。

但是当我在XCode调试中暂停程序执行时,我从Xcode看到的很奇怪,我看到了:

Thread 3
Queue: com.apple.root.default-priority
0 mach_msg_trap
7 -[NSRunLoop(NSRunLoop) run]
8 __37-[ViewController beginBackgroundTask]_block_invoke14
9 _dispatch_call_block_and_release
12 _pthread_wqthread

据我所知,8 __37-[ViewController beginBackgroundTask]_block_invoke14beginBackgroundTaskWithExpirationHandler- (void)beginBackgroundTask的阻止。但为什么Xcode仍显示7 -[NSRunLoop(NSRunLoop) run]

我在- (void)endBackgroundTask做错了吗? Xcode不会在此功能中警告我。

我们如何确保后台任务成功结束? Xcode Instruments可以提供帮助吗?

感谢任何回复。

enter image description here

0 个答案:

没有答案