
이번 강의에서는 Actor의 사용법에 대해 배웠다.
해당 문제를 만나기 위해서 먼저 여러 thread에서 공통된 class의 data에 접근하는 환경을 만들어야하는데, 이를 위해 Timer의 publisher를 사용한다.
let timer = Timer.publish(every: 0.1, tolerance: nil, on: .main, in: .common, options: nil).autoconnect()
그리고 서로 다른 view에서 싱글톤 class의 data에 접근하도록 만든다.
class MyDataManager {
static let instance = MyDataManager()
private init() { }
var data: [String] = []
func getRandomdata() -> String? {
self.data.append(UUID().uuidString)
print(Thread.current)
return self.data.randomElement()
}
}
이 코드에서 self.data.append(UUID().uuidString) 이 부분이 data race가 발생하는 지점인데, 그 이유는 서로 다른 뷰에서 0.1초마다 같은 class의 [String]에 append 하는데, append 하는 타이밍이 겹칠 수 있기 때문이다.
Xcode → Edit Scheme → Thread Sanitizer 를 키면 thread unsafe 한 경우 경고문을 보여주는데 다음을 확인할 수 있다.

private let lock = DispatchQueue(label: "com.MyApp.MyDataManger")completionHandler와 lock을 사용해서 다음과 같이 변경한다.func getRandomdata(completionHandler: @escaping (_ title: String?) -> Void ){
lock.async {
self.data.append(UUID().uuidString)
print(Thread.current)
completionHandler(self.data.randomElement())
}
}await를 사용해준다..onReceive(timer) { _ in
Task {
if let data = await manager.getRandomdata() {
await MainActor.run {
self.text = data
}
}
}
}actor MyActorDataManager {
static let instance = MyActorDataManager()
private init() { }
var data: [String] = []
func getRandomdata() -> String? {
self.data.append(UUID().uuidString)
print(Thread.current)
return self.data.randomElement()
}
// DONT WORRY ABOUT TRREAD SAFTY
nonisolated func getSavedData() -> String {
return "NEW DATA"
}
}nonisolated 키워드를 붙여준다.SwiftfulThinking 강의
https://www.youtube.com/watch?v=UUdi137FySk&list=PLwvDm4Vfkdphr2Dl4sY4rS9PLzPdyi8PM&index=10