NSURLSession dataTaskWithURL 非常 "slow"

NSURLSession dataTaskWithURL very "slow"

我的意思是 "slow",那种等待远程服务器超时以有效触发的回调(调用 vimeo 提要,解析它,然后在场景中显示 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
)

应该用别的东西来做这种任务?有没有办法'force'更新视图?

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

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

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

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

要解决此问题,您需要在后台线程中执行网络操作,然后最后在主线程中调用 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];
});