NSURLSession dataTaskWithURL非常“慢”

时间:2016-04-08 12:36:23

标签: ios ios9 nsurlsession rubymotion

我的意思是“慢”,回调类型等待远程服务器超时以有效触发(调用vimeo feed,解析它,然后在场景上显示uiviews)

我大多数时候都不知道它是如何运作的。我想在返回响应后立即从回调中填充我的视图

有下面的代码(rubymotion,但你可能会得到这个想法):

session = NSURLSession.sharedSession
url = NSURL.URLWithString(ALBUMS_URL)
downloadTask = session.dataTaskWithURL( url, completionHandler: lambda { |data, response, error|
    # 'puts' prints the result in the console, you get it as soon as the response arrives
    puts data
    # testing with a simple view 
    v = UIView.alloc.initWithFrame(CGRectMake(0,0,@width/2,200))
    v.backgroundColor = UIColor.blackColor
    self.view.addSubview v # ==> takes forever to effectively appear on the scene
})

我最终使用以下

在主线程中设置它
NSURLSession.sessionWithConfiguration(
    NSURLSessionConfiguration.defaultSessionConfiguration,
    delegate:nil,
    delegateQueue: NSOperationQueue.mainQueue
)

还应该用其他东西来做这种任务吗?有没有办法“强制”更新视图?

2 个答案:

答案 0 :(得分:1)

听起来数据需要30秒才能完全到达。为了更快地呈现数据,您可能必须使用委托,在收到数据时一次获取数据,使用知道如何处理部分接收数据的解析器,然后向您的数据添加更多数据用户界面收到其他数据。

编辑:不知怎的,当我之前回答这个问题时,我错过了这个事实,即只有在主线程上没有运行时才会失败。正如另一位评论者指出的那样,必须在主线程上启动任务或在块内使用dispatch_async,以便标签更改在主线程上运行。否则,UI将不会刷新,直到主线程上运行的其他代码导致重新绘制相关视图。

答案 1 :(得分:1)

你的UI花了这么长时间来更新的原因并不是因为操作花了这么长时间,而是因为NSURLSessionDataTask在后台线程中完成了。您可能知道,您不应该从后台线程进行UI更改,而只是主线程。

您将整个网址会话的回调放入主队列的解决方案"解决问题"这个问题,但不是正确的方法,因为你现在正在主队列中进行网络操作,对于可以在后台完成的事情(如网络操作)应该尽可能少。

要解决此问题,您需要在后台线程中执行网络操作,然后最后调用主线程中的UI更改逻辑。你可以做一个简单的dispatch_async()调用来创建一个更新UI的块,就像这样(对不起,我不熟悉RubyMotion,所以我在Objective-C中写这个):

// in the callback for NSURLSessionDataTask:
NSLog(@"%@", data);

// Dispatch the UI-related logic as a block on the main-thread
dispatch_async(dispatch_get_main_queue(), ^{
    UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0,0,width/2,200)];
    v.backgroundColor = [UIColor blackColor];
    [self.view addSubview:v];
});