Search code examples
swiftcombine

weak vs unowned inside Swift Combine closure


I don't understand the correct way of using self inside Combine closure

class ViewModel {
    var requestPublisher = PassthroughSubject<Void, Never>()
    var nextPageAvailabe = true
    private var subscriptions = Set<AnyCancellable>()

    init() {
        setupSubscriptions()
    }

    setupSubscriptions() {
        requestPublisher
        .filter { _ in self.nextPageAvailabe }
        .sink(receiveValue: {
            print("Received request")  
        }).store(in: &subscriptions)
    }
}

requestPublisher.send() executed from parent class. Using .filter { _ in self.nextPageAvailabe } will lead to memory leak. So I need to use [weak self] or [unowned self] inside filter {}. And both solve the memory leak issue, but I don't understand the correct way. I have read several articles but couldn't find the answer. So what is the correct way of using self inside Combine closure?


Solution

  • This capture list creates an unowned reference to self in the closure or completion block. In this case, if the view controller is deallocated before the closure or completion block is executed, it will cause a runtime crash. Therefore, it’s essential to use unowned references only when it is entirely sure that they will not become nil during block execution. Such a “safe” case would be when we store AnyCancellable in the same class where closure was defined.

    It seems, that in this case we can use unowned without any problems.