我有一个处理NSURLConnection的Download对象。
然后我有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
}
}
从外部(从 UI),我使用Download对象进行操作:Start、Pause、Resume、Cancel。在内部我正在改变它的状态,所以当下载完成或取消时,isActive设置为NO并且 while 循环应该结束。
如果我开始下载并让它完成(在后台,NSURLConnection完成并调用委托 - connectionDidFinish ...) ,这将起作用
如果我暂停/恢复 Download,下载将继续下载并完成(并更改其内部状态:isActive -> 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 循环?