iOS 앱 만들면서 뷰모델에 콜백 클로저를 하나 달았는데, 이 화면을 계속 들락날락하니까 메모리가 계속 쌓이더라고요. Instruments로 찍어보니 뷰컨트롤러가 dealloc이 아예 안 불려요. 문제 되는 코드가 대충 이런 식이에요.


class Loader {
  var onDone: (() -> Void)?
  func start() {
    onDone = { self.updateUI() }
  }
  func updateUI() { }
}


제가 이해하기로는 인스턴스가 onDone 클로저를 강하게 들고 있고, 그 클로저가 또 self를 강하게 잡으니까 서로 물고 있어서 ARC 카운트가 0이 안 되는 거 같은데 맞나요? 이거 어떻게 끊는 게 정석인지 궁금합니다. weak self 붙이면 된다는 말은 들었는데 정확한 문법이랑 이유를 알고 싶어요.