Prasad
Prasad

Reputation: 186

Combine Future Publisher is not getting deallocated

I am using the Combine Future to wrap around an async block operation and adding a subscriber to that publisher to receive the values.. I am noticing the future object is not getting deallocated, even after the subscribers are deallocated. The XCode memory graph and instruments leaks graph itself shows no reference to these future objects. I am puzzled why are they still around.

   func getUsers(forceRefresh: Bool =  false) -> AnyPublisher<[User], Error> {
        let future = Future<[User], Error> { [weak self] promise in
            guard let params = self?.params else {
                promise(.failure(CustomErrors.invalidData))
                return
            }
            
            self?.restApi.getUsers(params: params, forceRefresh: forceRefresh, success: { (users: [User]?, _) in
                guard let users = users else {
                    return promise(.failure(CustomErrors.invalidData))
                }
                
                promise(.success(users))
            }) { (error: Error) in
                promise(.failure(error))
            }
        }
        
        return future.eraseToAnyPublisher()
   }

Here's how I am adding a subscription:

   self.userDataService?.getUsers(forceRefresh: forceRefresh)
        .sink(receiveCompletion: { [weak self] completion in
            self?.isLoading = false
            if case let .failure(error) = completion {
                self?.publisher.send(.error(error))
                return
            }
            
            guard let users = self?.users, !users.isEmpty else {
                self?.publisher.send(.empty)
                return
            }
            
            self?.publisher.send(.data(users))
        }) { [weak self] (response: Array<User>) in
            self?.users = response
    }.store(in: &self.subscribers)

    deinit {
        self.subscribers.removeAll()
    }

This is the screenshot of the leaked memory for the future that got created above.. It's still staying around even after the subscribers are all deleted. Instruments is also showing a similar memory graph. Any thoughts on what could be causing this ??

enter image description here

Upvotes: 1

Views: 1157

Answers (1)

heckj
heckj

Reputation: 7367

Future invokes its closure immediately upon creation, which may be impacting this. You might try wrapping the Future in Deferred so that it isn't created until a subscription happens (which may be what you're expecting anyway from scanning the code).

The fact that it's creating one immediately is what (I think) is being reflected in the objects listed when there are no subscribers.

Upvotes: 1

Related Questions