SwiftUI - TCA Dependency : Dependency LifeTime , @TaskLocal

CodeCat·2024년 9월 9일

IOS SwiftUI TCA

목록 보기
15/20
post-thumbnail

안녕하세요 !

이번에는 TCA Dependency : Dependency LifeTime , @TaskLocal의 주제로 포스팅 해보려합니다

@TaskLocal

@TaskLocal은 값을 모든 곳에 값들을 전달하는 것을 가능하게 만들어주는 역할을 하는데요
전역변수와 같은거 아니야 라고 생각할 수 있지마 전역변수보다 더 안전하게 사용할 수 있도록 하는 특징을 가지고 있습니다

@TaskLocal의 특징:

  • 여러 작업이 경쟁 조건에 대한 걱정 없이 로컬에서 동일한 작업에 액세스가 가능
  • 정의된 특정 범위 내에서만 변경 가능 - 모든 부분이 변경 사항을 관찰하는 방식으로 값을 변경하는 것은 허용되지 않음
  • 기존 Task에서 생성된 새 Task에 의해 상속됨

@TaskLocal 사용 예제:

enum Locals {
    @TaskLocal static var value = 1
}

print(Locals.value)  // 출력: 1

Locals.$value.withValue(42) {
    print(Locals.value)  // 출력: 42
    
    Task {
        try await Task.sleep(for: .seconds(1))
        print(Locals.value)  // 출력: 42
    }
    
    print(Locals.value)  // 출력: 42
}

print(Locals.value)  // 출력: 1

이 예제에서 볼 수 있듯이, @TaskLocal 값은 withValue 메서드를 통해 특정 범위 내에서만 변경되며 Task 내에서만 변경된 값이 유지됩니다

값에 직접 접근하는 것이 불가능해요
이는 자체적으로도 해당 값을 변경할 수 없도록 get-only property에 포함 됩니다

만약에 withValue 메소드가 아닌 직접 접근이 가능하다면 값을 예상하기 어려윤 상황이 발생 할 수 있어요

예를 들어

print(Locals.value)  // 출력결과: 1
print(Locals.value)  // 출력결과: 42

위에 처럼 첫번째 출력은 1로 나오지만 두번째 출력이 되기전 다른 어디선가 Locals.value를 변경하는 코드가 발생할 수 있기 때문이죠

Concurrency

Swift의 Concurrency 기능을 사용하면 @TaskLocal 값을 더 넓은 범위에서 유지할 수 있는데요 이를 "작업 로컬 상속"이라고 부릅니다

TaskGroup, async let, Task { } 등으로 만든 작업들은 @TaskLocal 값을 상속 받으며
부모 작업의 @TaskLocal 값을 자식 작업에서도 사용할 수 있게 해줍니다.

Locals.$value.withValue(42) {
    print(Locals.value)  // 42
    Task {
        try await Task.sleep(for: .seconds(1))
        print(Locals.value)  // 42
    }
}

Task 내부의 코드는 1초 후에 실행되지만, 여전히 @TaskLocal 값 42를 유지합니다
이는 Task가 @TaskLocal 값을 상속받았기 때문이죠

주의 할점은 @TaskLocal은 모든 비동기 상황에서 상속되지는 않아요

Locals.$value.withValue(42) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
        print(Locals.value)  // 1
    }
}

이 예제에서는 DispatchQueue를 사용했기 때문에 @TaskLocal 값이 상속되지 않아요

따라서 원래의 값인 1이 출력됩니다

@TaskLocal은 값을 예측 가능하게 유지할 수 있게 해주지만, 모든 비동기 상황에서 완벽하게 작동하는 것은 아니라는 점을 이해하는 것이 중요해요

이상으로 포스팅 마무리 하겠습니다.

.
.
.

감사합니다.

profile
코드와 고양이의 만남

0개의 댓글