아래의 코드에서 PlannerDetailViewController은 왜 메모리에서 해제되지 않을까? 🤔
final class PlannerDetailViewController: UIViewController {
var date: Date?
var reloadCalendar: ((_ relodaCalendar: Bool) -> Void)?
private let viewModel = TodoManager()
private var subscriptions = Set<AnyCancellable>()
private lazy var addTodoButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(UIImage(systemName: "plus.circle"), for: .normal)
button.addTarget(self, action: #selector(didTappedAddTodoButton), for: .touchUpInside)
button.isEnabled = false
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
bind()
}
deinit {
print("deinit - PlannerDetailVC")
}
}
private extension PlannerDetailViewController {
func bind() {
inputTodoTextField.textFieldPublisher
.receive(on: DispatchQueue.main)
.sink { text in
self.addTodoButton.isEnabled = !text.isEmpty
}
.store(in: &subscriptions)
}
}
Set<AnyCancellable>()
을 사용하면 알아서 구독을 해제해 준다는 것을 믿고 클로저 내에서 약한 참조를 사용하지 않았다... 문제를 해결하기 위해 약한 참조 또는 미소유 참조를 사용해야 한다.
func bind() {
inputTodoTextField.textFieldPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] text in
self?.addTodoButton.isEnabled = !text.isEmpty
}
.store(in: &subscriptions)
}
메모리 누수는 치명적이기 때문에 반드시 클로저를 사용할 때는 약한 참조, 미소유 참조를 사용하는 습관을 들어야 한다는 것을 다시 깨닫는 기회였다.