본문 바로가기

Swift/RxSwift

[RxSwift] Reactive Programming / Memory Leak

728x90

Reactive Programming

  • Reactive Programming이란 비동기적 데이터 흐름과 전달에 관한 프로그래밍 패러다임이다.
  • Reative Programming의 핵심은 모든 것을 비동기적 데이터의 stream으로 간주하고 다양한 방법을 통해 이러한 비동기 이벤트를 처리하는 것이다.
    • 프로그래머가 특정 기능을 직접 정해서 실행되도록 처리하는 것이 아니라 시스템 이벤트가 발생되었을 때, 이를 알아서 처리할 수 있도록 하는 것이다.
  • 사용자의 입장에서는 Reative Programming을 기반으로 작성된 프로그램은 실시간성을 가진다.
    • 프로그래머가 작성한 순서와 다르게 사용자와 상호작용하며 그에 따라서 실시간으로 화면이 변하는 것이다.
  • 이를 실행하기 위해서 프로그램이 지속적으로 특정 값에 대한 관찰을 해야 한다.
    • 값을 관찰하다가 해당 값에 변화가 나타나면 특정 연산이 이뤄지는 것이다.
    • 사용자는 다양한 방법으로 해당 값에 비동기적으로 변화를 주는데, Reactive Programming에서는 이를 바로 파악하고 화면 혹은 다른 곳에 적절한 처리를 수행한다.

 

RxSwift 장점

  • Reactive Programming된 API를 제공하기 때문에 명확하고 명시적으로 비동기 데이터를 처리할 수 있다.
  • 다양한 비동기 처리방식을 하나로 통합함으로써 코드에 일관성을 제공한다.
  • 결국 확장이 어려웠던 아키텍처 패턴까지 해결할 수 있다.
  • 콜백 지옥에서 탈출하여 코드가 깔끔해지고 스레드관리가 용이해진다.

 

RxSwift 단점

  • 러닝커브가 높다.
  • 작동 기반이 비동기로 이루어져 있어 디버깅이 어렵다.
  • 클로저 사용이 많기 때문에 메모리 누수 및 순환참조가 일어날 수 있다. 이를 피할 수 있도록 캡처 리스트를 신경써야 한다.

 

🤔 왜 RxSwift를 사용하면 메모리 누수가 발생할까?

Swift는 ARC를 통해 메모리를 관리하고 클로저에서 self를 참조할 때 순환 참조가 발생하여 메모리 누수가 발생할 수 있다. 
- RxSwift를 사용하면 Observable 객체는 subscription을 할 때 필수적으로 클로저를 사용하고
- 값을 갖고 UI를 최신화 할 때 self.view와 같이 ViewController의 UI 객체에 접근하는 경우가 많으므로 클로저 안에서 self의 사용이 빈번하다. 

😇 어떻게 해결할 수 있을까?
1. 일반적으로 순환 참조가 발생할 때 해결할 수 있는 약한 참조로 코드를 수정하는 방법과 
2. 선언형으로 코드를 작성하면 된다. 
(2번 방법의 경우 여러 개의 property들을 한 번에 변경하고 싶을 때는 선언형 스타일을 적용하기 어렵다. 그렇기 때문에 이를 위해서는 RxCocoa에 포함된 Binder<>를 사용하면 여러 명령을 하나의 bindable property로 만들 수 있다.)