CombineCommunity / CombineExt

CombineExt provides a collection of operators, publishers and utilities for Combine, that are not provided by Apple themselves, but are common in other Reactive Frameworks and standards.
https://combine.community
MIT License
1.72k stars 151 forks source link

Memory leak issue with PassthroughRelay #167

Open just1103 opened 7 months ago

just1103 commented 7 months ago

Hello everyone,

I've been using CombineExt extensively in my projects and found it incredibly valuable. Recently, I encountered a memory leak issue with PassthroughRelay. Upon replacing it with PassthroughSubject, the retain cycle disappeared.

It appears that PassthroughRelay fails to release its subscriptions upon receiving completion, as similarly described in this PR #85.

I've come up with a potential solution for this issue and confirmed its resolution in my project, but I'm not fully proficient with Combine. So, any comments or suggestions would be greatly appreciated.


Original Subscription’s cancel method:

func cancel() {
    sink = nil
}

Solution:

// Call forceFinish() in Subscription’s cancel method. 
// And add self.sink = nil in forceFinish method.

func forceFinish() {
    self.sink?.shouldForwardCompletion = true
    self.sink?.receive(completion: .finished)
    self.sink = nil // added
}

func cancel() {
    forceFinish() // replaced
}