Upgrade to Pro — share decks privately, control downloads, hide ads and more …

鉄道信号設備の保守経験から考える Swift Concurrency のフェイルセーフ設計

Avatar for Kenta Igarashi Kenta Igarashi
September 13, 2026
130

鉄道信号設備の保守経験から考える Swift Concurrency のフェイルセーフ設計

Avatar for Kenta Igarashi

Kenta Igarashi

September 13, 2026

Transcript

  1. アプリでの『ヨシ!』 入力欄 iOSDC Japan 2026 送信 入力前は送信ボタン 無効 Copyright ©

    2026 East Japan Railway Company. All rights reserved. 入力が揃ったので送信 ✓ 送信 👈 ヨシ! #iosdc 7/48
  2. 【Swift①】checkCancellation() public func search(_ q: String) { searchTask?.cancel() Copyright ©

    2026 East Japan Railway Company. All rights reserved. #iosdc 19/48
  3. 【Swift①】checkCancellation() public func search(_ q: String) { searchTask?.cancel() // 古い検索にキャンセルを要求

    まず、前の Task をキャンセル Copyright © 2026 East Japan Railway Company. All rights reserved. #iosdc 20/48
  4. 【Swift①】checkCancellation() public func search(_ q: String) { searchTask?.cancel() // 古い検索にキャンセルを要求

    searchTask = Task { do { let new = try await api.search(q) results = new // 古い結果で上書きしてしまうかも… } catch { ⋮ Copyright © 2026 East Japan Railway Company. All rights reserved. #iosdc 21/48
  5. 【Swift①】checkCancellation() public func search(_ q: String) { searchTask?.cancel() // 古い検索にキャンセルを要求

    searchTask = Task { do { let new = try await api.search(q) try Task.checkCancellation() // 反映してヨシ? results = new } catch { ⋮ 反映の直前に、キャンセル済みか確認 Copyright © 2026 East Japan Railway Company. All rights reserved. #iosdc 22/48
  6. 【鉄道②】身近な鎖錠の例 A:洗濯機のふた B:脱水 ふたが開いている → 脱水できない Copyright © 2026 East

    Japan Railway Company. All rights reserved. 脱水中 → ふたが開かない #iosdc 27/48
  7. 【Swift②】actor reentrancy public actor PurchaseManager { public func buy() async

    throws { try await api.purchase() } } actor はデータ競合を防ぐが… Copyright © 2026 East Japan Railway Company. All rights reserved. #iosdc 32/48
  8. 【Swift②】actor reentrancy public actor PurchaseManager { public func buy() async

    throws { try await api.purchase() } } 購入ボタンが連打されると タップA try await manager.buy() タップB try await manager.buy() Copyright © 2026 East Japan Railway Company. All rights reserved. #iosdc 33/48
  9. 【Swift②】actor reentrancy public actor PurchaseManager { public func buy() async

    throws { try await api.purchase() } } 購入ボタンが連打されると タップA try await manager.buy() タップB try await manager.buy() await 中には、別の buy() の再入は禁止していない Copyright © 2026 East Japan Railway Company. All rights reserved. #iosdc 34/48
  10. 【Swift②】actor reentrancy public actor PurchaseManager { private var isPurchaseInProgress =

    false public func buy() async throws -> PurchaseOutcome { if isPurchaseInProgress { return .alreadyInProgress } defer { isPurchaseInProgress = false } isPurchaseInProgress = true // 二重購入を防ぐ状態ヨシ! try await api.purchase() return .purchased } } await より前に、拒否する状態を確定 Copyright © 2026 East Japan Railway Company. All rights reserved. #iosdc 35/48
  11. 【Swift③】withTaskCancellationShield defer { await withTaskCancellationShield { await tempFile.close() } }

    try await work() WWDC26で発表 Swift 6.4 新API Xcode 27 本処理がキャンセルで終了すると… Copyright © 2026 East Japan Railway Company. All rights reserved. #iosdc 42/48
  12. 【Swift③】withTaskCancellationShield defer { await withTaskCancellationShield { await tempFile.close() // 後始末

    } } try await work() WWDC26で発表 Swift 6.4 新API Xcode 27 defer に入り後始末へ進む Copyright © 2026 East Japan Railway Company. All rights reserved. #iosdc 43/48
  13. 【Swift③】withTaskCancellationShield defer { await withTaskCancellationShield { await tempFile.close() } //

    一時ファイルの後始末、完了👈ヨシ! } try await work() WWDC26で発表 Swift 6.4 新API Xcode 27 本処理がキャンセルされても、後始末は止めない。 Shield で後始末がキャンセルから守られる Copyright © 2026 East Japan Railway Company. All rights reserved. #iosdc 44/48
  14. まとめ 鉄道信号 Swift Concurrency 条件がそろわなければ、 進行を許可しない キャンセル済みなら反映しない 先の処理を守り、 競合する要求は通さない actor

    reentrancy フラグは await の前で 列車が着点に着くまで、 withTaskCancellationShield 予約した進路は解錠しない 後始末は止めない Copyright © 2026 East Japan Railway Company. All rights reserved. checkCancellation() #iosdc 45/48