我正在尝试在辅助线程中运行NSURLConnection异步(目标是iOS4),为此我创建了一个并发的NSOperation,我想我差不多了,但我不清楚以下内容:
1)在iOS4中NSOperationQueue addOperation在新线程中启动操作,因为使用GCD,基于Technical Q&A QA1712,但是,我的测试(模拟器和iPad)显示始终调用start()主线程,任何想法,我需要在这里检查:如果在主线程上然后产生一个新的?
2)如果通过addOperation()在辅助线程上实际调用了start,那么我可以通过在当前NSRunLoop上进行调度来启动我的异步NSURLConnection:
[self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.connection start];
与LinkedImageFetcher示例here类似,我不需要循环直到完成:
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!isCompelted);
假设我的自定义NSOperation start()在主线程上调用并且2)是正确的,我在start()中生成一个新线程来调用我的自定义main()方法:
[NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil];
在我的main()中,我需要运行当前的线程运行循环:
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!isCompelted);
这是我在并发NSOperation中设法运行NSURLConnection的唯一实例,但是我不确定我是否需要运行RunLoop,如果该线程是由GCD提供的技术说明状态,我可以吗?按照2)中的逻辑或者我仍然必须运行线程的runloop?如何测试GCD提供的线程?
非常感谢任何解释
答案 0 :(得分:9)
好吧,我最终解决了这个问题,所以人们可能会对细节感兴趣:
1)在主线程上调用了start(),因为我使用[NSOperationQueue mainQueue]而不是用[[NSOperationQueue allc] init]创建一个新队列。但是在NSOperation start()中检查当前线程是否是mainThread,然后直接从那里调用main()或者生成一个新线程(如果我们在mainThread上)并没有受到伤害。
2)我意识到LinkedImageFetcher对于理解运行循环和线程来说太复杂了,而且不必要,因为主题并不复杂。 start()方法中所需要的只是保持辅助线程运行循环,直到我们完成(isCompleted),NSURLConnection的所有运行循环都在监听来自连接的输入并触发回调(didreceivereponse, didreceivedata等。)。
3)是运行run循环是必要的,以便在相同的(在这种情况下是辅助)线程上获得连接回调。
有关详细信息,请参阅“线程编程指南”中的Run Loops。
答案 1 :(得分:0)
我不确定你想要实现的目标:NSURLConnection API有一个内置的异步方法initWithRequest:delegate:
你有什么特别的理由不能使用它吗?