NSURLSession dataTaskWithURL非常“慢”

问题描述 投票:0回答:2

我的意思是“慢”,回调类型等待远程服务器超时以有效触发(调用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
)

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

ios ios9 nsurlsession rubymotion
2个回答
1
投票

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

您将整个URL会话的回调放在主队列中的解决方案“解决”了这个问题,但不是正确的方法,因为您现在正在主队列中进行网络操作,这对于可以完成的事情应该尽可能少。背景(如网络运营)。

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

1
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.