[Swift] [iOS] Async, Await, Actor 1편 (Swift Concurrency Roadmap)

JB
3 min readJun 14, 2021

--

Swift 에서 비동기 프로그래밍을 구현하려면 GCD로 구현합니다.
예를 들면 테이블뷰의 reloadData() 메소드를 사용하려면

메인스레드에서 비동기에서 돌리는 방식 등으로 사용합니다. 이러한 간단한 구문은 가독성이 괜찮을 수도있지만, 아래와 같은 예시는 게으른(?) 개발자들에게는 귀찮음으로 다가옵니다.

이와같은 refreshPlayers 함수의 players 의 값을 completion Handler 를 처리하기위해선 refreshQueue 를 비동기적으로 처리하고있는데요. 이에대한 단점은

  • 너무 많은 일들을 한다
    함수를 호출하고, async하게 돌리고, escaping closure를 사용하고 players값이 셋팅되면 completion Handler를 호출하고.. (이하 더이상 설명하려면 손가락이 아파서생략)
  • 버그 유발의 가능성
    Completion Handler 에서의 self.players 는 어느 스레드에서 돌아야하는지? 데이터 레이스 유발 가능성
  • 메모리 관리에서의 지나치게 비효율적
    self 사용의 남발로 reference count operations 를 추가적으로 증가 → (compiler 에게 미안하다..)

Async, Await

위와 같은 문제점을 해결함과 동시에 효과적인 비동기적 처리를 위해 코루틴에서 영감을 받은
Async, Await, ActorSwift 5.5 에 추가된다고 합니다. (드디어 Swift Programming 공식문서 5.5 (Beta) 가 나와서 쓰는건 안비밀..)

위 같은구문은 이번 주제에서 소개해드릴 async, await, actor 를 사용하면

한 문장으로 너무 깔끔하게 해결됩니다. (편안하죠?)

  • refreshPlayer() 함수는 async 함수로 되고
  • gameSession에서 가져온 nickname 을 가져오기까지 await 하고 (또는 suspended하고)
  • nickname 값을 가져온다면 completionHandler 가 필요없이 players 값이 리턴됩니다.
  • await 키워드는 try 와 비슷하게 작동합니다.
  • 더이상 escaping closure 를 사용하기 위해 self 를 사용하지 않아도 됩니다.
  • allPlayersplayers 는 더이상 데이터 레이스 가 생기지 않습니다.

Actor

  • Reference Type
  • Entity가 꼬이지 않게 한번에 하나의 task만 access가 가능

의 특징을 갖고 있는 Actor 를 사용하여

와 같이 표현 할 수 있습니다.

이로 인해 GCD 를 사용할 때 필연적으로 생각하는

  • 데이터 레이스
  • 데드락

와 같은 이슈들을 해결할 수 있습니다.

Async, Await, Actor에 대해간단하게 알아보았고
2021년 6월 8일 에 업데이트된 Swift 5.5 Beta 번역편으로 2편으로 찾아오겠습니다~

--

--