我认为我发现了与Swift Combine的反跳运算符有关的内存泄漏。 这可能是泄漏,或者我做错了什么。 这是一个重现问题的简单示例:
@IBOutlet weak var currentValueLabel: UILabel!
var numberSubject = CurrentValueSubject<Int, Never>(0)
var bag = [AnyCancellable]()
override func viewDidLoad() {
super.viewDidLoad()
setupSubscription()
bag.removeAll()
}
func setupSubscription() {
numberSubject
.debounce(for: .seconds(0.5), scheduler: DispatchQueue.main)
.sink { [weak self] in self?.currentValueLabel.text = "\($0)" }
.store(in: &bag)
}
}
debounce
运算符的简单使用似乎导致malloc
泄漏(已使用Memory Debugger检查):
更新setupSubscription()
以抛弃debounce
似乎可以解决此问题:
func setupSubscription() {
numberPublisher
// .debounce(for: .seconds(0.5), scheduler: DispatchQueue.main)
.receive(on: DispatchQueue.main)
.sink { [weak self] in self?.currentValueLabel.text = "\($0)" }
.store(in: &bag)
}
如果使用此修改运行,并等待视图加载(也就是发生订阅,然后将其从数组中删除),您将注意到泄漏不再存在。 泄漏神奇地消失了。
有人可以告诉我我做错了什么吗?对我来说,这似乎是个错误。
谢谢!
答案 0 :(得分:2)
用内存图跟踪的模拟器中调试模式下的内存管理不是很实际。我在设备上使用Instruments进行了尝试,发现一个16位字节的malloc泄漏。我认为一个人不应该汗流sweat背,这是非常小的东西。您可以根据需要向Apple报告,但不要担心,要开心。
答案 1 :(得分:0)
首先,发布服务器将在其存活期间占用内存,这很明显。
如果您正在调试,并且您正在初始化接收器的屏幕中,那么您将看到它的内存使用情况。
您需要检查的是何时离开屏幕,如果内存使用情况仍然继续存在,并且因为您没有取消AnyCancellable
您需要始终牢记的是,当您将对象存储在“ [AnyCancellable]”中时,还需要在作业完成时对它们进行cancel(),在这种情况下,您应该实现以下目标:
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
for cancellable in bag { cancellable.cancel() }
}