【问题标题】:Release a queue in ARC在 ARC 中释放队列
【发布时间】:2014-06-06 10:34:07
【问题描述】:

我创建了一个队列,我在其中执行打印后台任务:

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

    _queue = dispatch_queue_create("q.myqueue.com", nil);
    dispatch_set_finalizer_f(self.queue, &myFinalizerFunction);
    background = UIBackgroundTaskInvalid;
    t = nil;

    [self beginBackgroundTask];
}

- (void)beginBackgroundTask {
    // Start the long-running task and return immediately.
    dispatch_async(self.queue, ^{
        UIApplication *app = [UIApplication sharedApplication];
        background = [app beginBackgroundTaskWithExpirationHandler:^{
            [self endBackgroundTask];
        }];

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

        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");

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

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

    NSLog(@"Ended!");
}

后台过期后,调用[self endBackgroundTask];但是当我通过“暂停程序执行”监视 Xcode 调试时,我仍然看到队列“q.myqueue.com”!

Thread 2
Queue: q.myqueue.com
0 mach_msg_trap
7 -[NSRunLoop(NSRunLoop) run]
8 __37-[ViewController beginBackgroundTask]_block_invoke
9 _dispatch_call_block_and_release
14 _pthread_wqthread

谁能解释为什么后台任务过期后Xcode调试中队列“q.myqueue.com”仍然存在?我想使用dispatch_release(self.queue),但 ARC 拒绝了。

谢谢

【问题讨论】:

    标签: xcode queue automatic-ref-counting release


    【解决方案1】:

    您对队列有很强的引用。只要 _queue 未设置为 nil,队列就会留在那里。设置 _queue = nil 就是你需要做的。请记住,只要有任何任务在其上运行,队列就会保持活动状态。

    顺便说一句,玩运行循环的唯一开发人员是那些非常聪明或非常愚蠢的人。我尽可能远离他们。

    【讨论】:

    • 谢谢,gnasher729。同意,我也不想玩运行循环!但是我需要一个在后台工作的计时器,所以我担心我别无选择。如果我评论[[NSRunLoop currentRunLoop] addTimer:t forMode:NSRunLoopCommonModes];[[NSRunLoop currentRunLoop] run]; 或两者兼而有之,则计时器不起作用!你有更好的方法吗?我很想知道。
    猜你喜欢
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    相关资源
    最近更新 更多