iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど
いわゆる、async/awaitのお話だ。
非同期関数 listPhotos() を同期で呼び出して値を受け取る。
import Foundation
func listPhotos(inGallery name: String) async -> [String] {
do {
_ = try await Task.sleep(nanoseconds: UInt64(1 * 1_000_000_000)) // 1秒待つ
} catch {}
return ["photoNames"]
}
Task {
let photoNames = await listPhotos(inGallery: "Summer Vacation")
print("\(photoNames)")
}
async 宣言すると関数は非同期となる。非同期関数を await で呼び出すと、結果が返るまで待つ。
非同期関数 listPhotos() を非同期で呼び出して、結果が返るのを待って、値を受け取る。async / await なコードは、非同期関数、または、@main で記された構造体、クラス、列挙型の static main()、Task からでしか呼び出せない。
import Foundation
func listPhotos(inGallery name: String) async -> [String] {
do {
_ = try await Task.sleep(nanoseconds: UInt64(1 * 1_000_000_000)) // 1秒待つ
} catch {}
return ["photoNames"]
}
Task {
async let photoNames = listPhotos(inGallery: "Summer Vacation")
print("\(await photoNames)")
}
非同期関数の戻り値を async let で代入すると、非同期で実行される。その戻り値を await をつけて参照すると、結果が返ってくるまで待つ。
非同期関数を反復処理する例。それには、対象がAsyncSequenceプロトコルに準拠している必要がある。
struct Demo {
struct AsyncDemo: AsyncSequence {
typealias Element = String
let num: Int
struct AsyncIterator: AsyncIteratorProtocol {
var num: Int
mutating func next() async -> Element? {
num = num + 1
return num.description
}
}
func makeAsyncIterator() -> AsyncIterator {
return AsyncIterator(num: num)
}
}
func getStr(num: Int) -> AsyncDemo {
return AsyncDemo(num: num)
}
}
すると、このように反復処理が記述できる。
Task {
let demo = Demo()
for await str in demo.getStr(num: 0) {
print(str)
_ = try await Task.sleep(nanoseconds: UInt64(1 * 1_000_000_000)) // 1秒待つ
}
}