トップ 最新 追記

Cocoa練習帳

iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど

2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|

2023-03-09 [Swift]Concurrency

いわゆる、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秒待つ
    }
}

トップ 最新 追記