如何在[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:distantFuture]之后唤醒线程?

时间:2012-10-04 09:40:18

标签: objective-c nsurlconnection nsthread nsoperation nsrunloop

我有一个下载对象,用于处理 NSURLConnection

然后我有 NSOperation 对象( DownloadOperation ),其中包含下载对象作为属性。

下载对象可以开始/暂停/恢复/取消

这是 DownloadOperation

的主要方法
- (void)main
{
    @autoreleasepool {

        BOOL isDone = NO;

        if (![self isCancelled]) {   
            [_download start]; //Download object start (creates NSURLConnection internally)
        }

        NSDate *distantFuture = [NSDate distantFuture];
        while(!isDone && ![self isCancelled]) {

            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:distantFuture];

            if (!_download.isActive) { //internal state of Download
                isDone = YES;
            }
        }

        [self completeOperation]; //this sets finished and executing flags
    }
}

从外部(来自用户界面),我使用下载对象操作:开始暂停恢复取消的。 在内部,我正在更改其状态,因此当下载完成或取消时, isActive 设置为,而循环应该结束。

如果我开始下载并让它完成(在后台, NSURLConnection 已完成并调用委托 - connectionDidFinish ...)< / p>

如果我暂停/恢复 下载,下载将继续下载并完成(并更改其内部状态: isActive - &gt; NO )。 暂停时我取消 NSURLConnection ,并在恢复时创建新的。

或者如果我取消下载,它也将处于非活动状态( NSURLConnection 被取消)。

但问题出在这里:

[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:distantFuture];在这些情况下(当我取消 NSURLConnection 时)永远不会返回,而我的“ if ”语句从未被处理过,因此 DownloadOperation 始终被视为正在运行,并且永远不会退出 NSOperationQueue

看起来没有可能被触发的事件会导致runloop被唤醒。

我试过

            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.05]];

这种作品但不是那么顺利,我不认为这是最好的解决方案。

我真正想知道的是,如何强制 NSRunLoop 唤醒(如何触发一些会导致它唤醒的事件)并继续我的while循环?

1 个答案:

答案 0 :(得分:2)

这就是我的所作所为。

好消息是我的应用程序中有通知,我确切知道下载时间是否正在发生变化。所以我创建了一个实例变量NSThread currentThread,在主要开头我调用了currentThread = [NSThread currentThread]

收到通知后,我知道应该让我的线程醒来,我打电话给:

[self performSelector:@selector(wakeUpThread:) onThread:currentThread withObject:nil waitUntilDone:NO];

- (void)wakeUpThread什么都不做,它是空方法,但这样做的目的是唤醒线程并导致我的运行循环继续。