這集的目的很明顯,就是想把耗時間的運作放到背景去執行,不要影響主要畫面的執行功能,不過作業寫出來還是有點不太一樣,不知道我寫得是不是正確的,第一題我把送達的食物數量計算放到extention Deliverable裡面,然後用if去判斷是否十個商品都送到,都送到再print,然後外面的item Forloop只有放 Task { await item.order() },印出來約3.25秒,不過我看解答是把計數放到defer去執行,雖然之前介紹過defer,但還是看不太懂解答的意思,第二題我寫得跟Jane的比較像,但url我是放在struct外面,fetch的function也是放在struct外面,不像Jane把它變成靜態屬性跟方法,forloop的程式碼一樣,但最終印出來順序跟解答不一樣,變成 > 網路請求是否在 Main Thread?false > 網路請求是否在 Main Thread?false > 印出貓咪知識是否在 Main Thread?true 🐈 貓咪知識:XXX > 印出貓咪知識是否在 Main Thread?true 🐈 貓咪知識:XXX > 網路請求是否在 Main Thread?false > 印出貓咪知識是否在 Main Thread?true 🐈 貓咪知識:XXX 但因為執行速度太快,無法判斷三個下載是否有干擾,因此也不知道是不是有寫對作業,另外在看thread的地方一直有 Class property 'current' is unavailable from asynchronous contexts; Thread.current cannot be used from async contexts.; this is an error in Swift 6 的警告是正常的嗎? 最後,我的專案裡面使用async優先進入main thread只有updateUI,但在fetch Data的部分我沒有使用await,是不是其實要把fetch Data改寫成使用await的code會比較理想呢?
@@ChaoCode 感謝老師回覆, Task.sleep(for)這個方法可以使用了 但是我比較想了解文件裡面的寫法代表的是什麼意思, where代表他要遵守的條件 但是Never == Success 這是什麼怪怪的條件 查文件也只有寫Available when Success is Never and Failure is Never. 也是說當成功=never與失敗=never的時候 才可以使用, 但是我還是沒有很明白這句英文表是的是哪一種狀況下會發生Never == Success?
影片最後講到的練習題連結在這裡~~ 👉tinyurl.com/swift217
終於講到 concurrency,這是最多人留言問會不會介紹的,所以準備得特別緊張,講的過程也覺得... 沒有白板好難講... 希望大家還是吸收😅
我學 async 其實是很久以前剛寫後端的事了,我寫了一個專案滿滿都是 async,但是我覺得我改版到第四次或第五次才真的理解
語法本身不難,畢竟就只是一律在 async 前面加上 await,但重點是要考慮到「非同步」造成的後續影響,很容易出現意料之外的情況和 bug,所以我一直強調看到 await 要記得,這一行和下一行之間可能出現很大的變化
Jane妳解釋得實在有夠清楚,超級感謝妳的影片
謝謝!
老師你的語速越來越穩了,超喜歡妳的語調跟音色
謝謝~~ 但我反而覺得我越來越不會講了 🤣
原來MainActor是新的寫法,之前用GCD一陣子了,還沒注意有新的API耶~~
這幾個都是 5.5 去年更新的寫法 本來只有支援 iOS15 但現在都有 backport 到 iOS13,我覺得 backport 之後就變得蠻實用了~~
太棒了,之前都只能找國外影片,現在有中文頻道會更好理解,謝謝老師~
可以請老師全英文再講一次嗎>
@@cowton0517 ???
@@cowton0517 我很看好你哦~哈哈哈哈
設計跟 try error 思路解釋清楚,第一個我覺得用中文講 swift 語法清楚直接完整的頻道. 感謝分享
寫作業的時候覺得把deliveredCount 傳進去覺得很髒,沒想到原來還有defer這種寫法,學習新知識了,感謝!
感謝分享!!! 一直不是很懂async跟await 在swift怎麼用 都被之前的寫法卡住 看完影片茅塞頓開!
老师会安排Combine的讲解吗?这个要安排进去就更好了,多谢多谢
Combine 應該是不會,我的 Combine 知識要到能講解還差太遠 😂
這集的目的很明顯,就是想把耗時間的運作放到背景去執行,不要影響主要畫面的執行功能,不過作業寫出來還是有點不太一樣,不知道我寫得是不是正確的,第一題我把送達的食物數量計算放到extention Deliverable裡面,然後用if去判斷是否十個商品都送到,都送到再print,然後外面的item Forloop只有放 Task { await item.order() },印出來約3.25秒,不過我看解答是把計數放到defer去執行,雖然之前介紹過defer,但還是看不太懂解答的意思,第二題我寫得跟Jane的比較像,但url我是放在struct外面,fetch的function也是放在struct外面,不像Jane把它變成靜態屬性跟方法,forloop的程式碼一樣,但最終印出來順序跟解答不一樣,變成
> 網路請求是否在 Main Thread?false
> 網路請求是否在 Main Thread?false
> 印出貓咪知識是否在 Main Thread?true
🐈 貓咪知識:XXX
> 印出貓咪知識是否在 Main Thread?true
🐈 貓咪知識:XXX
> 網路請求是否在 Main Thread?false
> 印出貓咪知識是否在 Main Thread?true
🐈 貓咪知識:XXX
但因為執行速度太快,無法判斷三個下載是否有干擾,因此也不知道是不是有寫對作業,另外在看thread的地方一直有 Class property 'current' is unavailable from asynchronous contexts; Thread.current cannot be used from async contexts.; this is an error in Swift 6 的警告是正常的嗎?
最後,我的專案裡面使用async優先進入main thread只有updateUI,但在fetch Data的部分我沒有使用await,是不是其實要把fetch Data改寫成使用await的code會比較理想呢?
嗨嗨,第一題的 defer 是每次這整個 Task 執行完要離開前會檢查目前送了幾個食物,如果跟總食物數量一樣就表示完成
不過這個判斷是否所有 Task 都結束,其實後面其實會教更好的做法~
第二題印出來的順序其實不重要,重點只是檢查網路請求必須是在背景 & 印出來的時候是在 main thread,所以你的結果是沒問題的
你的印出來的結果看起來像是你的系統只能同時背景跑兩個 thread,所以是兩個跑完之後才換第三個。如果你不確定的話,可以再放到專案中改用手機測試看看,應該就會可以跑三個
然後警告的部分是正常的,我這裡用 Thread.current.isMainThread 只是為了檢查作業,實際上寫專案時不會用這個
而會有這警告是因為 Swift 從 5.5~6 正在一步一步調整異步工作的方法,會慢慢關掉和限制一些舊的做法,現在都還是黃字警告,到 Swift 6 的時候就會是紅字了
最後你的專案的問題,你的意思是你現在 fetch data 是用舊的 api(要用 Result 或者 callback)的方式嗎?雖然沒有對錯之分,但如果不是為了配合最低 iOS 要求的話,我會建議一率都用新的 async api,比較好讀也比較好維護,也是未來 Swift 的方向~
@@ChaoCode 了解,不過我是從ios15開始學的,所以也不知道舊版的語法哪些可以用哪些不能用,以目前業界製作的app大多都會向下支援到哪個版本呢?
@@lyc7485 iOS15 就是 Swift 加入 async 語法的時候哦,不過 async 有被 backport 到 iOS13,但只是語法的部分,api 很多還是要 iOS15+ 才有
業界的話現行版本 -1 -2 我覺得都是合理的,但當然也有一些公司要求更多😅
如果Task的功能是把裡面的任務丟到其他thread處理,那在25:44的部分,加上MainActor 又強制所有內容丟回main thread執行,是否等於Task完全沒有意義? 或者Task只代表將任務獨立為非同步,而不能保證他要在哪個thread執行 謝謝
我也有这个疑问!!!!
好像是因为Task并不代表或者不一定代表丢到其他thread处理,却依然可以创建异步的任务
想請問ChaoCode老師
作業中的第一題的解答Task { defer {}} 應該不是在mainTread上
這樣好像會印出2個以上完成任務時間?
還想請教文件裡面定義的 Task where Success == Never, Failure == Never
這段的意思是永遠不會有成功失敗嗎(上網好像沒有找到有用的知識,自己亂猜的)
嗨嗨,第一題確實不是在 main thread 中執行,所以可能會印出很多次,也可能印不出來。這個後面會教比較好的做法~
我當時只想到先從同時執行多件事情開始練習就沒想到這點,不好意思~我來改一下,謝謝你提醒 😊
Never 代表的的確就是「不會發生」,同時也代表假如發生的話就要直接當掉(因為是非預期狀況)
不過這裡會這樣寫只是因為內建的 sleep 是宣告在這組 Generic 之下(可以在這看到:github.com/apple/swift/blob/5eb942ce563e3b49619e3e5af31ccfb6e82b0181/stdlib/public/Concurrency/TaskSleep.swift)
所以要用它就是要從這邊使用~
另外現在的版本已經不需要這個 extension 了哦,現在有 Task.sleep(for: ) 這個方法,可以直接放入秒數
@@ChaoCode
感謝老師回覆, Task.sleep(for)這個方法可以使用了
但是我比較想了解文件裡面的寫法代表的是什麼意思,
where代表他要遵守的條件
但是Never == Success
這是什麼怪怪的條件
查文件也只有寫Available when Success is Never and Failure is Never.
也是說當成功=never與失敗=never的時候
才可以使用, 但是我還是沒有很明白這句英文表是的是哪一種狀況下會發生Never == Success?
@@pig2000b 嗨嗨,Never 就是前面說的不會發生,所以成功是 Never、失敗是 Never 基本上就是不存在的。所以這個方法是被「靜態方法」,你並不會建立這個 Task 實例哦,只是要設定 extension 一定要明確寫出類型宣告才這樣寫~
想請問一下,如果有了 async/await 的功能,那還需要 combine 嗎?
感覺 combine 的功能,好像都可以利用 async 寫出來,而且更符合直覺內容,
( combine 感覺好難理解 😥)
很多人都會問這個問題
我個人覺得 async await 是完全取代了 GCD + completion + Result
至於 combine 的話,我覺得有一些重疊,但還是有我覺得 combine 寫起來比較順的,像是處理錯誤或是 streams(也可能只是我還不會習慣新寫法)
所以對我來說是兩個共存~
@@ChaoCode 就像chaocode说的,我理解的Async/Await 是提供提供的一套非常lower-level APIs. 取代了 GCD向现代编程迈进.
而combine,是一套提供超级多预设操作符来解决复杂业务场景的框架.
妳會不會下載檔案到sandbox的documents資料夾裡?
沒有試過耶,我只有存到文件的 Shared Playground Data 資料夾而。
感覺 FileManager 應該可以?但我不確定,因為 Playground 很多東西都要另外再 import 😔
@@ChaoCode 我的playgrounds不能import appkit,設定ios或macos都不能一樣耶,它卡到陰了
@@撞到牆 那 import SwiftUI 看看~裡面也有 NSImage 的
@@ChaoCodeimport SwiftUI, 一樣沒有NSImage
@@撞到牆 😔😔😔 Playground 的問題,我想你只能開專案試了
看到你用 Task
去查了一下最低版本支持
發現只支持13之後
(╯°□°)╯︵ ┻━┻
公司專案不使用工具包
用你的寫法大概可以少好一段代碼
心動但專案到底標是iOS 10
只能自己做小專案的時候用了⋯⋯
10?! 這是我聽過最低的了... 感覺維護起來好累喔🤯
@@ChaoCode 幾乎就是純objc 了,真的會遇到很神奇的Bug 😂
老師您好:首先非常感謝您這一系列的影片讓我獲益良多。
但我在影片範例照著練習時發現
for number in 1...5 {
Task {
work(name: "員工 \(number) 號")
}
}
執行時、發現雖然不會跑在Main thread
但一次只會跑一個Thread
不會像您影片上一樣
一次跑8個Thread
但如果用dispatchqueue.global().async
就可以跑多個Thread
不知道是因為什麼原因、
所以想問問看
再次感謝
你是在 Playground 上執行還是在其他專案中執行呢?
如果不是在 playground,因為Task 會繼承現有的 actor(後面幾集會講到),所以如果是在其他環境中可能會有不一樣的行為
如果是在 playground 還有這個問題的話,我就不太確定為什麼了,也許可以把 playground 的 platform 改成 macOS 看看?
@@ChaoCode
我是在Playground上運行的。
另外我把platform改成macOS就可以了、
非常感謝、這困擾了我很久~~