Global Actors in Swift (@globalActor) | Swift 동시성 #10

Sung Daegyu·2024년 3월 3일
post-thumbnail

Swift: Global Actors in Swift (@globalActor) | Swift Concurrency #10

Global Actor란?

  • Global Actor는 말 그대로 전역적으로 쓰일 수 있는 Actor이다. 전 강의에서 nonisolated를 통해서 actor 안에서 isolated 하지않게 지정할 수 있었다. 이와 정확히 반대 메커니즘이다.
  • Actor 밖에서 해당 actor와 isolated 시키고 싶을 때 global actor를 정의해서 쓸 수 있다.
  • Apple document의 정의

    A type that represents a globally-unique actor that can be used to isolate various declarations anywhere in the program.

  • Global Actor는 swift에서 protocol로 정의되어 있다.

Global Actor 사용 방법

  • Global Actor의 정의
    • global actor로 쓰일 struct, class 앞에 @globalActor 키워드를 붙여준다.
    • 전역적으로 쓰일 actor를 static var shared 변수에 할당해주면 된다.
    • 예시
      @globalActor struct MyGlobalActor {
        
        static var shared = ThisIsActorThatWantToBeUsedAsGlobal()
        
      }
  • Actor 밖의 변수, 함수 앞에 @MyGlobalActor 키워드를 붙이는 것으로 앞의 shared에 정의한 actor(ThisIsActor…AsGlobal)에 isolate 하게 할 수 있다.
    • 예를 들어 다음의 함수가 ThisIsActorThatWantToBeUsedAsGlobal 밖에 정의되어 있다고 하자.
      func getData() {
      	let data =  ["One", "Two", "Three", "Four", "Five"]
      	self.data = data
      }
    • getData() 함수를 ThisIsActorThatWantToBeUsedAsGlobal 안에 포함시키고자 하면 단순하게 @MyGlobalActor 키워드를 붙여주면 된다.
      @MyGlobalActor func getData() {
      	let data =  ["One", "Two", "Three", "Four", "Five"]
      	self.data = data
      }

MainActor도 Global Actor이다.

  • UI가 다시 그려지고 사용자가 상호작용하는 Main Thread에서 진행되야 한다.
    → 그래서 해당 변경사항이 진행되는 코드는 MainActor.run() 안에 넣어줬었다.
  • 다음과 같은 @Published 변수가 있다.
    class ViewModel: ObservableObject {
    	@Published var dataArray: [String] = []
    }
    → 이 변수가 변경되는 경우 View에서 UI가 다시 그려지기 때문에 Main thread에서 실행되어야 한다.
    • 따라서 다음과 같은 함수의 경우 `MainActor.run()` 을 붙여줌을 알 수 있다.
      class ViewModel: ObservableObject {
      
      	...
      
      	func getData() {
      	   let data =  ["One", "Two", "Three", "Four", "Five"]
      	   await MainActor.run {
      	     self.dataArray = data
      	   }
      	}
      }
  • 그런데, UI가 변경되는 코드를 일일이 확인해서 MainActor.run() 에 넣어주기는 너무 번거롭다. 심지어… 이 에러사항은 런타임에만 확인할 수 있다.
    • 💡 MainActor가 Global Actor라는 사실을 알고 있다면 compile 이전에 확인할 수 있다!
    • 바로 dataArray 변수 앞에 Main Actor와 isolate 되어 있다는 키워드를 붙여주는 것..!
      	@MainActor @Published var dataArray: [String] = []

정리

  • Global Actor는 해당 Actor의 확장으로 생각하면 되는 것 같다.
  • Main Actor도 Global Actor이다. UI의 변경과 관련있는 변수, 함수들 앞에 @MainActor 키워드를 붙여서 사전에 에러를 확인하자.
  • Singleton으로 관리되는 Actor의 경우에 사용된다.
    1. Main Thread
    2. 데이터베이스 layer
    3. 이미지 캐시
    4. Authentication

참고

https://www.youtube.com/watch?v=BRBhMrJj5f4&list=PLwvDm4Vfkdphr2Dl4sY4rS9PLzPdyi8PM&index=11

https://ahmadgsufi.medium.com/global-actor-3359c982541f

profile
대규의 개발로그

0개의 댓글