Stack over flow 에 질문을 남겨서 달린 답변과 테스트 결과 참고해서 추가 댓글 드립니다~
말씀대로 Task 는 현재 actor 의 context 를 따라가기 때문에, UI 내에서 생성한 Task 의 코드는 main actor 즉, main queue 에서 동작합니다. Main queue 는 serial 이기 때문에 1->3->2 로 동작합니다.
하지만 Playground 에서는 main actor 에서 Task 가 생성된 환경이 아니기 때문에, detached Task 가 생성됩니다 (실제로 Task { print(Thread.current.description) } 를 찍어보면 background 가 프린트 됩니다).
즉, Task 내의 print("2") 는 main thread 와 동시에 다른 thread 에서 실행될 수 있는 코드입니다.
그 밑에 있는 print("3") 은 Main Thread 에서 돌기 때문에, `2` 와 `3` 은 우선순위나 CPU 등의 환경에 따라 프린트 순서가 달라질 수 있습니다.
이전에 말씀 주신 환경은 아래와 같은 이유에 의해 결과가 노출된 듯 합니다
1. MainActor에서 실행되도록 하면 예상 동작 결과 확인
-> 1, 3 은 main thread 에서 돌아야하는데, 2 도 main 에서 돌게 지정했으므로 serial queue 의 특성에 따라 1->3->2
2. priority를 background로 하면 2->3 / 3->2 결과 왔다갔다
-> 기본은 high 로 생성되어있는데 (Task.currentPriority 로 확인 가능), 이걸 background 로 낮추면 3 이 먼저 실행될 가능성이 좀 더 높아짐. (하지만 가능성일 뿐 결과는 장담 못함)
비슷하게 app project 에서도 detached Task 로 생성하면 2->3, 3->2 의 순서 보장을 할 수 없는 상황이 되는데요,
print("1")
Task.detached {
print("2")
}
print("3")
참고로 저는 아래와 같이 detached task 의 priority 를 확 올리고, print("3") 을 print("3" + 1.description) 과 같이 복잡한 연산을 추가해주면 1->2->3 케이스가 좀 더 잘나오는 것 같더라구여
print("1")
Task.detached(priority: .userInitiated) {
print("2")
}
print("3" + 1.description)
결론적으로 말씀주신대로 "The task created by Task.init(priority:operation:) inherits the priority and actor context of the caller" 에 의해 발생한 동작 차이가 맞습니다
다만, 글에서는 이런 상황까지 고려해서 상황에 따라 2->3 이 프린트 될 수 있다고 추가 설명을 하는건 처음 Actor 를 접하는 독자들에게 혼란을 줄 것 같습니다. 처음에는 우선 Task 가 비동기 context 를 제공하기 때문에 3->2 로 될 수 있군~ 이라고 이해하도록 넘어가게 하고, 중간과 끝 부분에 각각 Task initializer가 actor isolation 을 상속하는 내용과, main actor 의 내용이 나와있기 때문에 이대로 유지하는게 흐름상 더 매끄러울 것 같아요! 참고로 만약 Playground 에서 1->2->3 이 프린트 되어서 혼란스러웠던 분이 있다면 요 댓글을 참고해달라고 간단히 써두겠습니다~!
혹시 추가적인 의견 있으면 말씀주세요~ 감사합니다.
참고 : https://stackoverflow.com/questions/77683271/the-behavior-of-task-seems-to-differ-in-playground-environments