【问题标题】:Task created in a session that has been invalidated在已失效的会话中创建的任务
【发布时间】:2020-06-23 10:54:46
【问题描述】:

我在 crashlytics 上遇到以下崩溃,我无法在我的设备上重现

Fatal Exception: NSGenericException
Task created in a session that has been invalidated

在下面一行

NSURLSessionTask *task = [self.session uploadTaskWithRequest:request fromFile:filePathURL];
[task resume];
[self.session finishTasksAndInvalidate];

我在委托方法中处理了会话失效

- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error {
    // Crashlytics logging
    [CrashlyticsKit setBoolValue:true forKey:@"URLSession_didBecomeInvalid"];
    self.session = [self createNewSession];
}

- (NSURLSession *)CreateSession {
    NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:SERVER_URL];

    if (@available(iOS 11.0, *)) {
        sessionConfig.waitsForConnectivity = YES;
    }
    return [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
}

上传新版本后,我仍然遇到同样的崩溃,并且在“didBecomeInvalidWithError”处根本没有 Crashlytics 日志!

知道如何解决这个崩溃吗?

【问题讨论】:

  • didBecomeInvalidWithError 曾经被调用了吗?我想我想知道的是:你确定这个方法是在某个真正是 URLSession 委托的对象中实现的吗? — 另外:您是否意识到 URLSession 保留它的委托?这会导致棘手的内存管理问题。你在做什么呢? — 另外,请显示createNewSession
  • 我已经更新了问题并添加了更多代码。请注意,该类是 Singlton,即委托存在于应用程序生命周期中,因为我需要在后台的多种情况下发送文件,而不仅仅是一次。
  • @matt 当我调试应用程序时代码到达didBecomeInvalidWithError 当它稍后完成上传文件时它在尝试上传文件时再次工作但在生产中我遇到了这个崩溃
  • 所以您正在开始一项任务并使会话无效(但由于某种原因挂在旧会话引用上)?并且您 100% 确定您不会在该会话中开始其他任务?
  • @Rob 所以你的意思是,只要我在用户使用应用程序时多次使用一个会话(而不仅仅是上传一个文件补丁),那么我不应该使它无效,因为将会使用用于时间线稍后的后续请求

标签: ios objective-c nsurlsession nsurlsessiontask


【解决方案1】:

如果您使会话无效,您将无法再次使用它。如果您尝试使用以前无效的会话,您将收到与我们分享的错误。

这让你有两个选择:

  • 如果您必须使会话无效,我建议您将 session 引用设置为 nil,这样您就不会意外再次使用它。如果您稍后必须执行另一个请求,您将实例化一个新的会话对象。

  • 如果您可能需要再次使用会话,您可以简单地避免使其无效。保留单个会话对象对内存的影响在很大程度上是无关紧要的。如果您要创建许多会话,这才是真正的问题。

坦率地说,后台会话非常复杂,以至于我需要一个非常有说服力的案例来处理多个会话(例如,每个会话都有自己的完成处理程序传递给我的应用程序委托)。如果可能的话,我会倾向于单后台会话模式。

【讨论】:

  • 能否有第三个选项来适当地处理(捕获)该异常?
  • @Shashikant - 不,您不会以编程方式捕获和处理异常,而是将它们从您的代码中完全删除。 (Swift 正式化了这个约定,甚至没有提供简单的方法来捕获异常,只处理抛出的错误,尽管命名相似,但这是一个完全不同的概念。)正如 Introduction to Exception Programming 所说,“你通常会处理这些类型的在创建应用程序时而不是在运行时出现异常错误。”
猜你喜欢
  • 2015-04-26
  • 2023-03-26
  • 2013-08-29
  • 2012-02-11
  • 2019-06-05
  • 2018-09-28
  • 1970-01-01
  • 2016-06-14
  • 2020-08-18
相关资源
最近更新 更多