我正在调查内存泄漏,并且使用Malloc选项,它看起来像我们拥有的类:
类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的财产应该是弱的还是无主的?
其次,如果是这样,原因是什么呢?
答案 0 :(得分:1)
正如URLSession
documentation所说:
会话对象保留对该委托的强引用,直到您的应用退出或明确使会话无效为止。
由于您的会话管理器具有对会话的强引用,并且会话具有对其委托的强引用,因此您具有强大的引用周期,在应用程序终止或会话失效之前不会解析。
如果你想避免这种情况,我不会使用URLSession
的弱引用。相反,我倾向于将URLSession
委托方法移动到独立的委托对象,而不是将它们保存在SessionManager
对象中。这将避免强大的参考周期。它也可能是一种更清洁的设计,符合单一责任原则。"
但应该认识到,这并没有真正改变应用程序的基本内存特性。该应用程序可能维护对会话管理器的引用,会话管理器维护对会话的引用,该会话维护对委托对象的强引用。在会话失效之前,不会释放与委托对象关联的内存。但它避免了强大的参考周期,否则可能会混乱你的调试内存图"分析
答案 1 :(得分:1)
你的假设是对的。来自documentation:
讨论
此委托对象负责处理 身份验证挑战,制定缓存决策,以及 处理其他与会话相关的事件。会话对象保持一个 在您的应用退出或明确提交之前,对此代理的强烈引用 使会话无效。如果你没有使会话无效,你的 应用程序泄漏内存直到它退出。
这基本上意味着你所写的内容。你有双面强大的参考周期。正如你所说,你可以通过将urlSession
设置为weak
引用来打破它。然而,这可能(但不是必须)导致不良副作用,例如在创建它之后立即丢失urlSession
,因为没有对象捕获对它的强引用。
我建议
P.S。
如果您的主要目标是研究内存泄漏,那么在调试内存图以分析对象计数器和Xcode的提示(紫色矩形中的感叹号)时,查看Xcode的左侧面板会很有帮助。