NSURLSession应该是一个弱势属性

时间:2017-12-26 21:51:44

标签: ios nsurlsession

我正在调查内存泄漏,并且使用Malloc选项,它看起来像我们拥有的类:

enter image description here

类SessionManager已

@property(nonatomic, strong) NSURLSession *urlSession;

- (instancetype)initWithConfiguration(NSURLSessionConfiguration)configuration {
    if (self = [super init]) {
    _urlSession = [NSURLSession sessionWithConfiguration:configuration delgate: self delegateQueue:_sessionQueue];


    }

    return self;
}

我不知道怎么读这个,除非我能猜到,它是NSURLSession保留在SessionManager以及对NSURLSession有强引用的SessionManager。 NSURLSession的财产应该是弱的还是无主的?

其次,如果是这样,原因是什么呢?

2 个答案:

答案 0 :(得分:1)

正如URLSession documentation所说:

  

会话对象保留对该委托的强引用,直到您的应用退出或明确使会话无效为止。

由于您的会话管理器具有对会话的强引用,并且会话具有对其委托的强引用,因此您具有强大的引用周期,在应用程序终止或会话失效之前不会解析。

如果你想避免这种情况,我不会使用URLSession的弱引用。相反,我倾向于将URLSession委托方法移动到独立的委托对象,而不是将它们保存在SessionManager对象中。这将避免强大的参考周期。它也可能是一种更清洁的设计,符合单一责任原则。"

但应该认识到,这并没有真正改变应用程序的基本内存特性。该应用程序可能维护对会话管理器的引用,会话管理器维护对会话的引用,该会话维护对委托对象的强引用。在会话失效之前,不会释放与委托对象关联的内存。但它避免了强大的参考周期,否则可能会混乱你的调试内存图"分析

答案 1 :(得分:1)

你的假设是对的。来自documentation

  

讨论

     

此委托对象负责处理   身份验证挑战,制定缓存决策,以及   处理其他与会话相关的事件。会话对象保持一个   在您的应用退出或明确提交之前,对此代理的强烈引用   使会话无效。如果你没有使会话无效,你的   应用程序泄漏内存直到它退出。

这基本上意味着你所写的内容。你有双面强大的参考周期。正如你所说,你可以通过将urlSession设置为weak引用来打破它。然而,这可能(但不是必须)导致不良副作用,例如在创建它之后立即丢失urlSession,因为没有对象捕获对它的强引用。

我建议

  • 确保这部分代码确实是一些重要的代码 内存泄漏(因为现在它看起来像一个简单的单例,不应该占用太多内存)
  • 如果真的让内存泄漏 - 重新考虑您的架构,以便invalidate sessions

P.S。

如果您的主要目标是研究内存泄漏,那么在调试内存图以分析对象计数器和Xcode的提示(紫色矩形中的感叹号)时,查看Xcode的左侧面板会很有帮助。