Objective c 如何在[[NSRunLoop currentRunLoop]运行模式:NSDefaultRunLoopMode beforeDate:distantFuture]之后唤醒线程?
我有一个下载对象,它处理NSURLConnection 然后我有了NSOperation对象(DownloadOperation),它将Download对象作为属性 下载对象可以启动/暂停/恢复/取消 这是下载操作的主要方法Objective c 如何在[[NSRunLoop currentRunLoop]运行模式:NSDefaultRunLoopMode beforeDate:distantFuture]之后唤醒线程?,objective-c,nsurlconnection,nsthread,nsoperation,nsrunloop,Objective C,Nsurlconnection,Nsthread,Nsoperation,Nsrunloop,我有一个下载对象,它处理NSURLConnection 然后我有了NSOperation对象(DownloadOperation),它将Download对象作为属性 下载对象可以启动/暂停/恢复/取消 这是下载操作的主要方法 - (void)main { @autoreleasepool { BOOL isDone = NO; if (![self isCancelled]) { [_download start]; //
- (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),我使用下载对象进行操作:开始、暂停、恢复、取消。
在内部,我正在更改其状态,因此当下载完成或取消时,isActive将设置为否,而while循环应结束
如果我开始下载并让它完成(在后台,NSURLConnection完成并调用delegate-connectiondifinish…),这项功能就会起作用
如果我暂停/恢复下载,下载将继续下载并完成(并更改其内部状态:isActive->NO)。
暂停时我取消NSURLConnection,恢复时我创建新的
或者,如果我取消下载,它也将处于非活动状态(NSURLConnection已取消)
但问题是:
[[NSRunLoop currentRunLoop]运行模式:NSDefaultRunLoopMode beforeDate:distantFuture]在这些情况下(当我取消NSURLConnection时),代码>永远不会返回,并且我的“if”语句也永远不会被处理,因此此下载操作始终被视为正在运行,并且永远不会退出我的NSOperationQueue
看起来没有可能触发的事件会导致runloop被唤醒
我试过了
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.05]];
这种方法很有效,但不是很顺利,我不认为这是最好的解决方案
我真正想知道的是,如何强制该nsrunlop唤醒(如何触发一些会导致其唤醒的事件)并继续我的while循环?以下是我所做的
好的是,我的应用程序中有通知,我确切地知道下载何时发生变化。因此,我创建了一个实例变量NSThread currentThread
,并在main的开头调用currentThread=[NSThread currentThread]
在我收到通知后,我知道该通知会导致我的线程被唤醒,我会呼叫:
[自执行选择器:@selector(wakeUpThread:)onThread:currentThreadwithObject:nil waitUntilDone:NO];
-(void)wakeUpThread
不执行任何操作,它是空方法,但其目的是唤醒线程并使我的运行循环继续