RxSwift소개 및 비동기 프로그래밍이란

Written by Tejay
on 

RxSwift소개 및 비동기 프로그래밍이란

1. RxSwift란

RxSwift is a library for composing asynchronous and event-based code by using observable sequences and functional style operators, allowing for parameterized execution via schedulers.

  • RxSwift에 대한 이론이다. RxSwift는 관찰 가능한 시퀀스와 함수 스타일 연산자를 사용하여 비동기 및 이벤트 기반 코드를 작성하고 스케줄러를 통해 매개 변수화 된 실행을 허용하는 라이브러리라는데 잘 이해가 안간다. 그냥 대강 풀어보면 코드를 통해 반응된걸 감지하고 그걸 통해 다른 동작을 하는 비동기 형태의 라이브러리라고 생각하면 될거 같다. 사실 이걸 보기 전에 강의를 몇가지 봤지만 이해가 쉽지 않아 이론을 다시 공부하려고 한다.

2. Asynchronous 프로그래밍이란

  • RxSwift에 이론에 보면 비동기에 대한 설명이 있다. 여기서 얘기하는 비동기 프로그래밍에 대해 알아보자. iOS 앱에 보면 수많은 순간들이 있다.
    • 버튼을 누를 때
    • 텍스트 필드 포커싱에 따라 키보드가 동작할 때
    • 인터넷으로 이미지를 다운 받을 때
    • 데이터를 저장할 때
    • 오디오 재생할 때
  • 위에 것 말고도 수많은 순간들이 있다. 이것들은 겉으로 보기에는 같은 시간에 동작한다. 키보드가 스크린에서 사라질 때, 오디오를 일시정지하려고 하면 키보다가 스크린에서 완전히 사라진 후에 오디오가 일시정지하게 된다.
  • 프로그램의 다른 비트들은 다른 실행에 대해 막을 수 없다. iOS는 다양한 스레드에서 다른 작업을 수행하고 디바이스의 CPU의 다른 코어에서 수행할 수 있는 API들을 제공한다.

Cocoa와 UIKit 비동기 API

  • 그러나 실제로는 병렬로 실행되는 코드를 작성하는 것은 다소 복잡하다. 왜냐하면 각각 병렬로 실행되는 코드가 어떤것이 먼저 끝나고 업데이트되는지 알기 어렵기 때문이다. 이걸 해결하기 위해서 대부분은 프로젝트에서 애플이 제공하는 비동기 API를 많이 사용하고 아래의 것을 사용했을 것이다.
    • NotificationCenter: 사용자의 기기가 방향을 바꾸거나 키보드와 같은 이벤트가 발생할 때마다 사용했을 것이다.
    • Delegate: 클래스와 클래스간의 언제 끝날지 모를 때 많이 사용한다.
    • Grand Central Dispatch: 직렬 대기열에서 순차적으로 실행되어야 할 때나 동시에 많은 작업이 필요할 떄 사용한다.
    • Closure: 클래스간에 전달할 수 있는 분리된 코드 조각을 만들어 클래스가 코드를 실행할지 여부, 횟수 등을 결정할때 사용한다.
  • 일반적인 클래스의 대부분은 비동기적이고 모든 UI 요소들도 비동기이기 때문에 앱 코드 전체가 어떤 순서로 실행하는 아는 것은 불가능하다.결국 앱은 유저의 입력, 네트워크 활동 또는 다른 OS의 이벤트와 같이 외부적인 요소에 따라 다르게 실행된다. 아마 앱이 실행될 때마다 이런 외부적인 요소들 때문에 코드가 순서가 다를 것이다.
  • 엄청 읽었는데 결국 좋은 비동기는 만들기 어렵다 라는걸 알리는 글이었다.

비동기 프로그래밍 용어

1. 상태, 특히 공유된 mutable(가변) 상태

  • 노트북을 예로 들면 노트북은 처음사용할 때랑 몇일 아니 계속 사용하다보면 느려지거나 멈출 때가 있다. 노트북의 하드웨어나 소프트웨어와 같은 스펙은 그대로인데 말이다. 이것은 바로 상태 때문인데 이 상태는 노트북의 메모리에 있는 데이터, 디스크에 저장된 데이터, 네트워크를 통해 남은 흔적들을 말한다.

2. 명령형 프로그래밍

  • 명령형 프로그래밍은 간단히 말하면 명령을 내려서 상태를 변경하는 것이다. 따라서 매우 명확하다.
  • 명령형 코드는 컴퓨터가 이해할 수 있는 코드와 유사하다. 하지만 이 명령형 코드는 위에서 말한 공유된 가변 상태인 경우가 포함됐을 때는 비동기 프로그래밍을 쓰는 것은 매우 어렵다.
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    setupUI()
    connectUIControls()
    createDataSource()
    listenForChanges()
}
  • 위에 경우를 보면 많은 메소드를 순차적으로 사용했다. 하지만 순차적이기만 하지 매우 불안한 코드이다. 누군가 이 순서를 바꾸게 되면 이 코드는 완전히 다르게 작동을 할 수 있기때문이다.

3. 부작용

  • 위에서 살펴보면 비동기 프로그래밍의 부작용은 딱 2가지로 이부분을 통해 문제를 해결할 수 있다.
  • 부작용은 현재 범위 외부의 상태로 변경된다. 위의 코드를 예로 들어보면 마지막 부분을 생각해보면 connectUIControls()는 일종의 이벤트를 UI 구성요소에 연결하는 것이다. 하지만 이것이 실행된 후 상태가 변경이 되면 연결된 이벤트의 동작은 다르게 바뀌게 된다.
  • 디스크에 저장된 데이터를 수정하거나 스크린에 있는 Label에 텍스트를 업데이트할 때마다 부작용은 발생하게 된다.
  • 부작용을 발생하는 문제는 컨트롤하는 방법 내에서 발생한다. 우리는 어떤 코드가 부작용을 일으키고 데이터를 단순히 처리하고 출력하는지 결정할 수 있어야 한다.
  • RxSwift는 이것을 해결하기 위해 존재한다.

4. 선언 코드

  • 명령형 프로그래밍에서는 하고 싶은대로 상태를 변경할 수 있다. 함수형 프로그래밍에서 부작용은 없다. RxSwift는 명령형과 함수형 프로그래밍을 결합한 것이다.
  • 선언 코드를 사용하여 동작을 정의할 수 있고, RxSwift는 관련된 이벤트가 있을 때마다 불변의 고립된 데이터의 입력을 제공한다.
  • 이 방법을 통해 비동기 코드를 사용할 수 있지만 for 루프와 같은 역할을 하게 만든다. 즉 변경 불가능한 데이터로 작업하고 순차적이고 결정론적인 방식의 코드를 실행하는 것이다.
  • 이 부분은 읽기만 해서는 이해가 잘 되지 않는다. 앞으로 더 공부하면서 알게 되겠지….

5. 반응형 시스템

  • 반응형 시스템은 추상적은 용어이다. 그리고 아래의 특성을 대부분 또는 전부 포함하는 웹 또는 iOS앱을 포함한다.
    • Responsive(반응): 항상 UI의 상태를 최신 상태로 유지한다.
    • Resilient(복원성): 각각의 동작은 격리되어 정의되고 유연한 에러 복구를 제공한다.
    • Elastic(탄성?): 코드는 다양한 작업을 다루고, 종종 lazy 기반의 데이터를 수집하고 이벤트를 조절하고 자료를 공유하는 기능을 한다.
    • 메세지 기반: 구성요소는 재사용성과 고립 그리고 라이프사이클과 클래스 분리를 향상시키는 메세지 기반의 통신을 사용한다.