我想我发现了一个与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泄漏(使用内存调试器检查):

更新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)
}如果您使用此修改运行,并等待视图加载(也称为订阅发生,然后将其从数组中删除),您将注意到泄漏不再存在。泄漏神奇地消失了。
谁能告诉我我是不是做错了什么?在我看来这是个bug。
谢谢!
发布于 2020-01-13 12:05:31
在使用内存图跟踪的模拟器中,调试模式下的内存管理并不是很真实。我在一个设备上使用Instruments进行了尝试,我发现一个16字节的malloc泄漏。在我看来,一个人不应该为小事而烦恼,这是非常小的事情。如果你愿意,你可以向苹果报告,但除此之外,别担心,祝你快乐。
发布于 2020-11-02 22:55:53
首先,只要它还活着,出版商就会占用内存,这是显而易见的。
如果您正在调试,并且您在初始化接收器的屏幕中,那么您将看到它的内存使用情况。
您需要检查的是,当您离开屏幕时,内存使用量是否仍然有效,而且由于您没有取消AnyCancellable,内存使用量将继续存在
您需要始终记住的是,当您在"AnyCancellable“中存储对象时,您还需要在作业完成时取消()它们,在您的情况下,您应该实现以下内容:
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
for cancellable in bag { cancellable.cancel() }
}https://stackoverflow.com/questions/59708086
复制相似问题