Swift Memory Part.3

만사·2021년 2월 13일
0

메모리

목록 보기
4/4
post-thumbnail

Retain Cycle 끊기

클로저를 사용할 때 메모리 누수가 발생할 수 있다는 것을 알았다 iOS개발을 할 때 특별히 자주 사용하는 것 중 Notification.center를 사용할 때, 콜백 함수를 사용할 때, 특히 콜백은 뷰 컨트롤러간에 데이터를 전달하는 가장 쉬운 방법 중 하나이기 때문에 쉬운 만큼 주의해서 처리해야 한다.

  • Notification Center 끊기
  1. 추가한 observer를 사용한 이후 제거(removeObserver)하는 것을 잊지 말자!
#1. addObserver(forName:object:queue:using:)
#2. addObserver(_:selector:name:object:)

노티피케이션에 사용되는 addObserver는 두가지인데, #2를 사용하는 경우 removeObserver를 호출 할 필요가 없지만, #1를 사용하는 경우에는 꼭 호출하여야한다.

  1. retain cycle을 피하기 위해 observer를 약한참조로 선언한다. 보통 observer를 선언할 때, NSObjectProtocol로 선언하기도 하는데
weak var observer: NSObjectProtocol?

위와 같이 약한잠조로 선언하는 것이 좋다.

  1. observer의 클로저를 사용하는 경우 retain cycle을 피하기 위해 획득 목록(capture list)를 사용.
observer = NotificationCenter.default.addObserver(forName: .saveDateTime, object: nil, queue: OperationQueue.main)
{ [unowned self] (notification) in
      let vc = notification.object as! ViewController
      self.dateLabel.text = vc.formattedDate
}
  • 콜백함수 사용할 때 retain cycle 끊기
    콜백 함수를 사용할 때 유의할 점은 참조하는 개체에 대한 RC가 0보다 높은지 체크하는 것이기 때문에, RC를 감소시키거나 애초에 RC를 증가시키지 않아야 한다.

다음과 같은 방법으로!
1. weak 사용 (RC를 증가시키지 않음)
2. unowned 사용 (RC를 증가시키지 않음)

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "toDestinationVCSegue" {
        let popup = segue.destination as! DestinationViewController
        popup.showTimePicker = false
            
        popup.onSave = { [unowned vc = self] (data) in
            vc.dateLabel.text = data
        }
    }
}
  1. 참조 개체를 nil로 설정 (참조 횟수 감소)
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "toDestinationVCSegue" {
        let popup = segue.destination as! DestinationViewController
        popup.showTimePicker = false
            
        popup.onSave = { (data) in
            self.dateLabel.text = data
            self.popup = nil //개체 참조가 끝난 후 꼭 RC감소!
        }
    }
}

0개의 댓글