【问题标题】:Why is NSURLSession dataTaskWithURL significantly slower vs NSData dataWithContentsOfURL?为什么 NSURLSession dataTaskWithURL 比 NSData dataWithContentsOfURL 慢得多?
【发布时间】:2015-05-12 02:49:46
【问题描述】:

我正在尝试从我的服务器下载一个 94KB 的图像文件。我尝试了两种方法:使用NSURLSession dataTaskWithURLNSData dataWithContentsOfURL

NSURLSession:

Globals *global = [Globals getInstance];

// GET request to /mobile/image
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/mobile/image/%@", [global rootUrl], self.photoId]];
NSURLSession * session = [global session];
NSDate *start = [NSDate date];
[[session dataTaskWithURL:url completionHandler:^(NSData *imgData, NSURLResponse *response, NSError *error) {
    NSLog(@"Time taken: %f", [[NSDate date] timeIntervalSinceDate:start]);
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
    if ([httpResponse statusCode] != 200) {
        // error
    } else {
        dispatch_async(dispatch_get_main_queue(), ^ {
            UIImage *image = [UIImage imageWithData:imgData];

            CGFloat width = self.photoImageView.frame.size.width;
            CGFloat height = image.size.height / image.size.width * width;
            self.imageHeight.constant = height;

            self.photoImageView.image = image;
        });
    }
}] resume];

NSData:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {
    Globals *global = [Globals getInstance];

    // GET request to /mobile/image
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/mobile/image/%@", [global rootUrl], self.photoId]];
    NSDate *start = [NSDate date];
    NSData *imgData = [NSData dataWithContentsOfURL:url];
    NSLog(@"Time taken: %f", [[NSDate date] timeIntervalSinceDate:start]);
    UIImage *image = [UIImage imageWithData:imgData];

    CGFloat width = self.photoImageView.frame.size.width;
    CGFloat height = image.size.height / image.size.width * width;

    dispatch_async(dispatch_get_main_queue(), ^{
        self.imageHeight.constant = height;
        self.photoImageView.image = image;
    });
});

这是我的 NSLog 的输出,显示他们完成了多长时间:

NSURLSession:

Time taken: 6.585221
Time taken: 3.619189
Time taken: 4.408179
Time taken: 9.931350
Time taken: 3.689192

NSData:

Time taken: 0.157747
Time taken: 0.135785
Time taken: 0.576947
Time taken: 0.462661
Time taken: 0.337266

下载一个简单的NSData,但我需要稍后使用NSURLSession进行另一个类似的图像下载任务,因为我需要登录会议。

我想知道我是否无意中发现了 NSURLSession 的一个奇怪错误,是否它应该慢得多,因为它具有会话的所有开销,或者我做错了什么。

编辑:

我想通了,谢谢大家的帮助!

我用这个项目的所有连接创建了一个全新的项目,它表现良好。

问题:之前的VC多次调用dataTask。我完全困惑为什么这会影响这个 VC。原来这个类被称为 ViewController(默认名称),而这个 VC 是继承 ViewController 而不是 UIViewController。

因此,从这个 ViewController 的 viewDidLoad 调用 [super viewDidLoad] 实际上是在调用之前的 VC 并重新运行所有这些 dataTask。

如有疑问,请检查会话中的所有其他连接。

【问题讨论】:

  • 用会话的配置(NSURLSessionConfiguration。我将从缓存开始)看看是否有什么对时间有很大影响可能是值得的。
  • 我没有费心去缓存,因为我也没有为 NSData 缓存。 (两者都完全干净。) 至于我的会话配置:NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];NSURLSession *session = [NSURLSession sessionWithConfiguration:config]; 这几乎是默认设置,我没有在其他任何地方更改任何配置。
  • 当我查看 NSURLSession 的网络使用情况时,它似乎在下载任务的中间下降到零 KB/s,然后在几秒钟后返回,重复直到完成。它可能与在后台运行有关吗?
  • 问题不在于上面的代码。问题也不在于NSURLSession,这是一段非常健壮的网络代码。提供的代码不足以重现您描述的问题。或许您可以构造 the simplest possible example 来体现您所描述的问题,并与我们分享?
  • @pchiang 您应该继续发布您的结论作为“答案”,而不是用您的发现编辑问题。见Can I answer my own question?

标签: ios performance nsdata nsurlsession


【解决方案1】:

您遇到了线程问题。 不要在后台线程中运行该代码(NSURLSession 代码)!在主线程上运行它。别担心,这不会阻塞主线程; NSURLSession 的全部意义在于 it 异步操作,因此您不必这样做。

【讨论】:

  • 您的论点是,如果您碰巧在后台线程中使用NSURLSession,您会看到这样的延迟吗?与NSURLConnection 不同,NSURLSession 在您想要运行它的任何线程中都表现得非常好。
  • @Rob 不,我认为他的线程问题在其他地方;我们不知道的事情正在争论中。我只是想让他离开那个后台线程,因为它们很难处理。
  • 同意,问题出在其他地方,而不是到目前为止问题中提供的代码中。
  • 我想通了,谢谢你的帮助!我创建了一个具有所有连接的全新项目,并且表现良好。问题:之前的VC多次调用dataTask。我完全困惑为什么这会影响这个 VC。原来这个类被称为 ViewController(默认名称),而这个 VC 是继承 ViewController 而不是 UIViewController。因此,从这个 ViewController 的 viewDidLoad 调用 [super viewDidLoad] 实际上是在调用之前的 VC 并重新运行所有这些 dataTask。
  • 这很好,但我认为我不应该为此获得任何“接受”!我们猜测问题出在其他地方,但仅此而已。
猜你喜欢
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 2017-12-26
  • 2011-01-25
  • 2012-12-20
  • 1970-01-01
  • 1970-01-01
  • 2017-05-10
相关资源
最近更新 更多