--- title: 'Task' tags: SwiftUI disqus: hackmd --- **目錄:** [TOC] ## Task * Concurrency 的語法都是建立在「Task」之上 `` (async let、Task、TaskGroup) `` * Task 可以設定優先度、可以被取消 `` 沒有設定的時候是直接套用啟動位置的優先度 `` `` 如圖,TaskGroup 的優先度就會是上面的.background ``  `` 取消的方式 ``  `` 取消不會是一瞬間完成的,Swift 會讓你的程式碼執行到合適的時機在取消 `` `` 合適的時機就是: await、跟主動設定可取消的地方(try Task.checkCancellation()) ``  * 結構化 / 非結構化的 Concurrency  - 結構化的容易從閱讀理解、能自動管理錯誤和取消 - 非結構化的更有彈性,可以從任何地方啟動,也能透過 Task 從其他地方取消任務 ## SwiftUI 中的 async 任務 ```swift= .onAppear { Task { await doSomething() } } ``` ```swift= .task { await doSometing() } ``` - 執行的時機一樣: - 畫面<font color="red">出現在渲染的 View 結構前</font>執行 - 自動在Main Thread 中執行 - 在沒有做 detached 的情況,它們會在這個同一個 View 的 Context 裡面,也就是會自動繼承 View 的 actor - 預設優先度不同: - onAppear: Task.currentPrority - task: userInitiated - .onAppear 生命週期不會和 View 綁定 - 如果要達成 View 消失就取消,要自己寫在 onDisappear 裡面取消 - .task 生命週期自動和 View 綁定 - <font color="red">當 View 消失時自動取消</font> - task 中的新的 Task 不會和 View 的生命週期綁定 -  ## SwiftUI 中的 Task 特性 會繼承 View 的 actor,且跟著畫面消失自動被取消  會繼承原本的 actor,但不會因為畫面消失而被取消  完全獨立的,不會繼承任何東西,也不會因為畫面消失而被取消  ## async 要放在哪裡? - 盡可能用 .task + 結構化 concurrency 完成 `` 因為你只要看到 View 消失,你就會知道這些任務都一起被取消了,而結構化的 concurrency 是為了確保這裡面的子任務也會隨著 View 消失一起被取消 `` - 如果 View 的生命週期跟 task 不搭: - 把 task 推到更前面的畫面 - 不要在 View 中處理 - 留下 Task reference 做清理 ## Task 練習 * 所有 async 任務都是在 Task 中執行 * 結構化 / 非結構化的 Concurrency `` 差別在於,結構化的會自動在上面的任務被取消的時候,把它的相關子任務都跟著取消 `` * Task 預設繼承原本所在位置的 actor `` 意思就是它們會有一樣的優先度,可以存取到一樣的 local 變數 `` * Task.detached 不會繼承原本的 actor ```swift= Task { await doSometing() } ``` ```swift= .task { await doSometing() } ``` 兩種都是一樣是發生在 Task 裡面,只是下面這個是它已經在某個 Task 之中
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up