我有一个下载对象,用于处理 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循环?
答案 0 :(得分:2)
这就是我的所作所为。
好消息是我的应用程序中有通知,我确切知道下载时间是否正在发生变化。所以我创建了一个实例变量NSThread currentThread
,在主要开头我调用了currentThread = [NSThread currentThread]
。
收到通知后,我知道应该让我的线程醒来,我打电话给:
[self performSelector:@selector(wakeUpThread:) onThread:currentThread withObject:nil waitUntilDone:NO];
- (void)wakeUpThread
什么都不做,它是空方法,但这样做的目的是唤醒线程并导致我的运行循环继续。