iOS,NSURLConnection:委托不同的线程callback?
我怎样才能让NSURLConnection调用它的委托方法从一个不同的线程,而不是主线程。 我试图搞乱scheduleInRunLoop:forMode:但似乎并没有做我想要的。
我必须下载一个大文件,并频繁地中断主线程,以至于一些正在发生的渲染开始变得波涛汹涌。
NSURLRequest * request = [NSURLRequest requestWithURL:url]; NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]; NSRunLoop * loop = [NSRunLoop currentRunLoop]; NSLog(@"loop mode: %@",[loop currentMode]); [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; [connection start];
另外一件我没有看到的东西是“模式”只有两种模式被logging下来,所以没有太多真正的testing。
有任何想法吗?
谢谢
有几个选项:
- 在实现委托方法时,请使用
dispatch_async
。 - 在后台线程上启动连接计划。
你可以这样做后者:
// all the setup comes here dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSRunLoop *loop = [NSRunLoop currentRunLoop]; [connection scheduleInRunLoop:loop forMode:NSRunLoopCommonModes]; [loop run]; // make sure that you have a running run-loop. });
如果要保证正在运行哪个线程,请将调用适当地replace为dispatch_get_global_queue()
。
如果你想在一个单独的线程执行下载,我敢肯定这些是你正在寻找的机器人…
- (void) dispatchRequest{ self->finished = NO; NSMutableURLRequest* request = //Formulate your request NSThread* download_thread = [[NSThread alloc] initWithTarget:self selector:@selector(downloadThreadLoop:) object:request]; [download_thread start]; } - (void) downloadThreadLoop:(NSMutableURLRequest*) request{ NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; while(!self->finished]){ //This line below is the magic! [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; } } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ //... } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ //... } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ //... } - (void)connectionDidFinishLoading:(NSURLConnection *)connection{ //... self->finished = YES; }
如果你确实需要在一个新的线程中下载,可能会更容易detachNewThreadSelector:toTarget:withObject:
,setup(and destroy)一个NSAutoreleasePool
,然后使用NSData
的dataWithContentsOfURL:
之一的同步select器。 这将不会使用asynchronousNSURLConnectionDelegate
。
因为这个调用是同步的,直到文件下载完成才会返回,这会阻塞主线程,但是因为你在新线程中,所以不会。 请注意,这通常是令人沮丧的行为。 主线程中是否有其他代码可以优化?
NSURLConnection已经在asynchronous执行主线程的下载。 如果我理解你的问题,你想委托消息被发送到主线程以外的线程? 你不能这样做,因为你不能修改NSURLConnection的内部实现。 我可以想到两种方法来模拟这个。
-
创build一个
NSURLConnection
的sublcass(例如MyURLConnection
),它将自己指定为自己的委托。 请注意,这会产生一个有意的保留周期,所以要小心。MyURLConnection
应该定义一个支持NSURLConnectionDelegate
的新delegate
。 我们称之为finalDelegate
。 当MyURLConnection
处理它自己的委托消息时,将它们转发或分配给任何你喜欢的线程的finalDelegate
。 -
类似于选项#1,但没有子类。 在主线程上处理
NSURLConnection
委托方法,并将它们转发/分派给你喜欢的任何线程。
主要的区别是,如果你想要一个可重复使用的子类,或者这是一个一次性的实现。
编辑:添加了如何在后台运行代码的build议
如果你要在后台处理响应,我将使用操作或大中央调度。 不需要搞乱运行循环和创build线程。 查看Apple的“ 并发编程指南” 。
- 在iOS 7中的accessibilityTraits支持
- 离开范围时,Swift在CFRelease中崩溃
- 反向工程iOS应用程序-iOS 11版(第1部分)
- 我们可以从iPhone的联系人列表中访问emailids吗?
- 用键盘上的button显示UIView,就像在Skype,Viber信使(Swift,iOS)
- 应用程序窗口预计在应用程序启动结束时具有根视图控制器
- 使用自动布局在CollectionView的CollectionViewCell中自动调整图像大小
- 排名前10的iOS SDK:排名前10的安装最多和排名前10的未安装iOS SDK
- searchUITableView单元格时忽略特殊字符的UISearchBar