Fix retain cycles
Fix retain cycles
Resolved retain cycles by capturing self weakly in async closure and Combine sink subscription. This prevents Downloader from being held in memory due to strong references in URLSession and Combine.
Report
- Issue: Retain cycles in
Downloaderclass. - Symptoms: The
Downloaderinstance remains in memory after its use, potentially leading to increased memory usage and resource leakage. - Cause: Strong references to
selfin asynchronous closures and Combine subscriptions. - Resolution: Used
[weak self]to capture self weakly in both thegetAllTasksclosure and the Combinesinksubscriber. - Status: Fixed in this pull.
This commit resolves the retain cycle issues, ensuring proper memory management for Downloader instances.
Analysis
The Downloader class was found to have potential retain cycles due to strong references to self within an async closure and a Combine sink subscription. These strong references prevent the Downloader instance from being deallocated, leading to memory leaks.
Problem Areas
-
Async Closure in URLSession
getAllTasks: The closure passed tourlSession?.getAllTasksin the initializer referencedselfstrongly, which could prevent the instance from being released if the closure retains it. -
Combine in
waitUntilDoneMethod: The Combinesinksubscriber inwaitUntilDoneheld a strong reference toself, potentially causing a retain cycle as Combine retains its subscribers until they are explicitly canceled or deallocated.
Solution
To prevent retain cycles, I've modified the code to capture self weakly in both the async closure and the Combine.