Using sink(receiveCompletion:receiveValue:) in a local scope?

As far as I know, AnyCancellable will automatically call the cancel() on the deallocation, so I have to keep a strong reference to it somewhere.

But sometimes it would be much useful if we can just use a Publisher in certain scope.

For example, with 3rd-party Future/Promise libraries, I can do something like this without worrying whether to keep the reference to AnyCancellable.

// using 3rd-party Future type.
func getMessage() -> Future<String, Error> { ... }

getImage()
    .onSuccess { value in print(value) }

When comparing to the Future type in Combine framework, how do I achieve the same?

// using Combine builtin Future type.
func getMessage() -> Future<String, Error> { ... }

// I have to keep the reference strongly.
self.cancellation = getMessage()
    .sink(
        receiveCompletion: { ... },
        receiveValue: { value in print(value) }
    )

I guess AnyCancellable actually prevents us creating unexpected memory leaks, but that also means I have to accept this little inconvenience?

I think I find the answer, I can explicitly use Sink subscriber to achieve it.

Future<String, Error> { promise in

    DispatchQueue.global().asyncAfter(deadline: .now() + 3.0) {

        promise(.success("Hello"))

    }

}
.receive(
    subscriber: Subscribers.Sink(
        receiveCompletion: { completion in print(completion) },
        receiveValue: { value in print(value) }
    )
)
1 Like