【问题标题】:Combine Future Publisher is not getting deallocatedCombine Future Publisher 没有被释放
【发布时间】:2020-04-09 18:58:36
【问题描述】:

我正在使用组合 Future 来环绕异步块操作并向该发布者添加订阅者以接收值。我注意到未来对象没有被解除分配,即使订阅者被解除分配。 XCode 内存图和仪器泄漏图本身没有显示对这些未来对象的引用。我很困惑为什么他们还在。

   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()
   }

这是我添加订阅的方式:

   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()
    }

这是上面创建的未来泄漏内存的屏幕截图。即使订阅者全部删除,它仍然存在。 Instruments 也展示了类似的内存图。有什么想法可能导致这种情况吗??

【问题讨论】:

  • 你用调试器确认你进入了deinit,对吗?
  • 是的,我做到了..流程中的所有其他对象都在被释放。我唯一的猜测是这个未来的承诺目前在异步操作完成块中得到解决。我在想可能是这个块在执行操作时没有被持有它的其他对象释放..
  • 你能检查deinit是否被调用?我可能是错的,但不确定store(in: &amp;self.subscribers) 是否会导致保留周期,您可以将其删除并将其分配给 AnyCancellable 变量吗?
  • 运气不好,同样的问题

标签: ios swift combine


【解决方案1】:

Future invokes its closure immediately upon creation,这可能会影响这一点。您可以尝试将 Future 包装在 Deferred 中,以便在订阅发生之前不会创建它(这可能是您在扫描代码时所期望的)。

它立即创建一个的事实(我认为)反映在没有订阅者时列出的对象中。

【讨论】:

  • 谢谢...我认为泄漏是由异步块中的引用循环引起的...
猜你喜欢
  • 1970-01-01
  • 2013-05-24
  • 1970-01-01
  • 2021-11-20
  • 2011-06-01
  • 2019-08-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多