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];
});
我的意思是 "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];
});