View in English

  • Apple Developer
    • 今すぐ始める

    「今すぐ始める」を詳しく見る

    • 概要
    • 学ぶ
    • Apple Developer Program

    最新情報

    • 最新ニュース
    • Hello Developer
    • プラットフォーム

    プラットフォームを詳しく見る

    • Appleプラットフォーム
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    特集

    • デザイン
    • 配信
    • ゲーム
    • アクセサリ
    • Web
    • Home
    • CarPlay
    • テクノロジー

    テクノロジーを詳しく見る

    • 概要
    • Xcode
    • Swift
    • SwiftUI

    特集

    • アクセシビリティ
    • App Intent
    • Apple Intelligence
    • ゲーム
    • 機械学習とAI
    • セキュリティ
    • Xcode Cloud
    • コミュニティ

    コミュニティを詳しく見る

    • 概要
    • 「Appleに相談」イベント
    • コミュニティによるイベント
    • デベロッパフォーラム
    • オープンソース

    特集

    • WWDC
    • Swift Student Challenge
    • デベロッパストーリー
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Center
    • ドキュメント

    ドキュメントを詳しく見る

    • ドキュメントライブラリ
    • テクノロジー概要
    • サンプルコード
    • ヒューマンインターフェイスガイドライン
    • ビデオ

    リリースノート

    • 注目のアップデート
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • ダウンロード

    ダウンロードを詳しく見る

    • すべてのダウンロード
    • オペレーティングシステム
    • アプリ
    • デザインリソース

    特集

    • Xcode
    • TestFlight
    • フォント
    • SF Symbols
    • Icon Composer
    • サポート

    サポートを詳しく見る

    • 概要
    • ヘルプガイド
    • デベロッパフォーラム
    • フィードバックアシスタント
    • お問い合わせ

    特集

    • アカウントヘルプ
    • App Reviewガイドライン
    • App Store Connectヘルプ
    • 近日導入予定の要件
    • 契約およびガイドライン
    • システムステータス
  • クイックリンク

    • イベント
    • ニュース
    • Forum
    • サンプルコード
    • ビデオ
 

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • すべてのビデオ
  • 利用方法

その他のビデオ

  • 概要
  • Summary
  • トランスクリプト
  • コード
  • Swiftの新機能

    Swiftに関するアップデートを確認しましょう。日々の作業における使いやすさの向上、並行処理の改善、高パフォーマンスのコードにおける安全性強化など、Swiftの最新の進化を紹介します。Embedded Swiftにおける、ワークフローや言語間の相互運用性の改善点やアップデートについても学びます。

    関連する章

    • 0:07 - Introduction
    • 0:44 - Everyday Language Improvements
    • 1:55 - anyAppleOS Availability
    • 3:02 - @diagnose Attribute
    • 3:52 - Module Selectors (::)
    • 5:59 - Library Updates
    • 6:16 - Standard Library
    • 7:31 - Swift Testing Updates
    • 9:29 - Subprocess 1.0
    • 10:14 - Foundation
    • 11:59 - Beyond Apple Platforms
    • 12:35 - Swift–C Interoperability (@C attribute)
    • 15:09 - Swift-Java
    • 16:03 - Editor support
    • 16:44 - WebAssembly (Wasm) & JavascriptKit
    • 18:08 - Embedded Swift
    • 19:59 - Performance Tuning
    • 21:29 - Optimizer Control: @inline(always) & @specialized
    • 24:29 - Ownership System & Noncopyable Types
    • 26:18 - Iterable Protocol & Borrow/Mutate Accessors
    • 28:57 - New Standard Library Types: UniqueBox, UniqueArray, Ref
    • 31:11 - The Future of Swift

    リソース

    • Swift Blog
    • Explore documentation on swift.org
    • Swift Forums
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC26

    • gRPCとSwiftによるリアルタイムのアプリやサービスの構築
    • Swift Testingへの移行
  • このビデオを検索

    こんにちは Swiftチームの Beccaです。

    チームメンバーのEvanと私から いくつかの改善点を紹介します Swift 6.3と6.4の開発で 行った改善点です。 まず言語への変更をいくつか 紹介します 日々のコーディングを 効率化するものです。 次にEvanが重要なライブラリの アップデートについて説明します XcodeやAppleプラットフォーム以外での サポートの進展も紹介します。 その後パフォーマンスを チューニングする専門的な機能を紹介します 安全性を損なわずに パフォーマンス重視のコードに対応します。 そして最後にEvanが Swiftの開発へのフォローや 貢献方法をお伝えします。 まず日々利用するシンプルな 改善点から見ていきましょう。

    ほとんど気づかないような 小さな問題が解消されたものもあります まず小さな変更点から 確認しましょう。 たとえば以前はoptional型に someやanyを使う場合 括弧で囲む必要がありました。 Swiftの演算子優先順位の 規則によるものでしたが やや形式的すぎました。 Swift 6.4ではその括弧を 省略できるようになりました コンパイラは意図通りに 解釈してくれます。 エラーを暗黙的に無視すると 警告が表示されるようになりました Swift Concurrencyのタスクから スローされたエラーの場合です タスク内でエラーを 処理するよう促します またはタスクを保存して 後でエラーを確認します。 deferブロックからasync関数を 呼び出せるようになりました。 @unchecked Sendableが必要な クラスがある場合 weak varプロパティを 持つためであれば そのプロパティをweak letに 変更してイミュータブルにできます Sendableチェックを 有効にできるようになります。 型がSendableであるべきでない場合は 新しいチルダSendable構文で 明示的に宣言できます。 サブクラスがSendableになることは 妨げません。 internalとprivateプロパティが 混在するstructは 2番目のメンバーワイズ イニシャライザを持ちます プロジェクト内の他のファイルから 使用できます。

    確実に気づく変更点もあります。 Appleのエコシステムは過去20年で 大きく成長しており SwiftコードのAvailability属性も それに伴い増加しています。 昨年Appleはこの問題に 取り組み始めました OSリリースのバージョン番号を 統一することで対応しました。 Swiftはさらにそれを 発展させています すべてのプラットフォーム名を "Any Apple OS"に集約できます。 対象のすべてのプラットフォームで availabilityが一致するなら すべてのOSを 一度に指定できます 例外がある場合はanyAppleOSで デフォルトを設定して 例外に対してより具体的な 属性を追加できます。 #if os条件でも 同様に機能します コードの一部を完全に コンパイル対象外にできます。 年月とともに変化するものに APIもあります。 進化に伴い古いAPIは 非推奨になることがあります 新しいバージョンへの 移行を促すためです。 しかしすぐに移行できない 場合もあります 新しいAPIが大きく異なり 適応に時間が必要な場合です。 一時的にこれらの警告を 無効にできたら便利ではないでしょうか プロジェクトの他の部分に 影響を与えずに。

    それが可能になりました。 @diagnose属性を使うと 特定の警告の動作を変更できます 特定の宣言内で。 deprecated declarationの 警告グループを無視するよう設定したり その箇所だけ警告を 非表示にできます。 デフォルトでオフの警告を 選択的に有効にすることもできます。 たとえばstrict memory safetyを 有効にして セキュリティクリティカルな 関数で unsafe APIの使用を 確認できます。 または特定の警告を エラーとして扱えます。 ここでは将来エラーになる 警告をアップグレードして 今すぐエラーとしています。 これにより多くの 柔軟性が得られます。 Swift 6.3には2つのモジュールが 同じ名前のAPIを持つ場合に より適切に処理する 新機能があります。 たとえばRocketモジュールに 型があるとします 実際の100メートル級の SaturnVロケットを表す型です 一方GiftShopToysモジュールには 子供サイズのSaturnVロケットの モデルを表す型があります。

    同じファイルで両方の モジュールをインポートすると Swiftはどちらを使いたいか 判断できずエラーになります。 これを解決するには ドット構文を使う方法があります Rocket.SaturnVはまず Rocketモジュールを検索し その中でSaturnV型を 探します 他にSaturnVが存在しても 影響を受けません。 通常はこれで解決しますが うまくいかない場合もあります。 たとえばRocketモジュールに Rocketという型もある場合はどうでしょう 何が起きるか説明します Swiftは型名を モジュール名より優先します そのためRocket型を 指定していると判断し その中でSaturnVという メンバーを探します。 見つからない場合は エラーになります。 Swift 6.3ではこの問題を解決するために ドットをダブルコロンに変更します。 この新しい構文は モジュールセレクタと呼びます 左側の名前は常に モジュール名として扱われます。 SwiftはRocket型を無視して Rocketモジュールに直接アクセスし 目的の型を 簡単に見つけられます。 この構文はメソッドや プロパティ名にも使えます 型が同じ名前のメソッドを 持つ場合に便利です 2つの異なるモジュールの extensionから取得する場合です。 間違ったメソッドを呼び出すと 問題になりますから。 モジュールセレクタは 非常に便利です 制御できない2つのモジュール間で 競合がある場合に役立ちます。 たとえばSwiftUIと使用中の パッケージが両方View型を持つ場合 モジュールセレクタで 問題を解消できます。 また防御的に使うことも 良い方法です マクロ展開や 自動生成コードでは特に有効です プロジェクトに何が インポートされているか不明なためです。 ただし名前の競合が生じるよう APIを意図的に設計することは推奨しません モジュールセレクタで 区別するために。 コードが明確であっても エラーメッセージやドキュメントが 分かりにくい場合があります。 ですから、やめましょう。 言語の新機能を確認したところで 重要なライブラリのアップデートを Evanが紹介します。

    これらの言語改善はすべて 同じ目標を持っています 余分なノイズなしに 意図を正確に表現できるようにすることです。 同じ目標が日々使う ライブラリのアップデートにも引き継がれます。 標準ライブラリ、Swift Testing、 Subprocess、Foundationです。

    まず標準ライブラリの アップデートから見ていきましょう 特にタスクキャンセルの 新しいツールについてです ディクショナリの変換と ファイルパス操作も紹介します。 タスクのキャンセル状態を 確認することが重要ですが 高コストな処理を 開始する前に 実際に処理を実行したい 場合もあります タスクがキャンセルされた後でも ファイルを破損しないよう データのディスク書き込みを完了する場合などです。 タスクキャンセルシールドを 使用できるようになりました。 シールド内ではタスクキャンセル チェックが常にfalseを返します。 この領域は短く保つことが重要です 開始済みの処理を完了するか ロールバックすることに集中します。 ディクショナリのマッピングも アップデートされました。 mapValuesは古い値のみを マッピングクロージャに渡しますが 新しい値の計算にキーが 必要な場合 手動で新しいディクショナリを 構築する必要がありました。 mapKeyedValuesを 呼び出せるようになりました キーと古い値の両方を マッピングクロージャに渡して 新しい値を計算します。 プログラムはファイルパスを 操作することが多くあります。 プラットフォームごとの ファイルパスの表現に微妙な差異があります 正確に処理することが 難しい場合があります。 今年 標準ライブラリに 新しいfilepathの型を追加しました Swift Systemの型を基にしており 正確な処理が容易になります。

    Swift 6.4のテストでは テストの動作をより細かく制御できます 致命的でない問題の表示や テストケースの動的スキップが可能です。 Issue.recordで記録する問題の 重大度レベルを設定できます。 警告に設定すると 調査する価値のある問題を テストケースに表示できます CIワークフローを ブロックするほどではない問題です。 Test.cancel APIを呼び出すことで テストを動的にキャンセルできます。 パラメータ化テストでは 特に効果的です 実行すべきでない 個々の引数をキャンセルできます テストを最後まで実行したり 失敗させたりせずに済みます。 不安定なテストに 対処することがあります。 swift testコマンドに テストを繰り返す新機能が追加されました 成功または失敗するまで 繰り返し回数の上限も 制御できます。 テストが成功するまで 繰り返す設定にすると 失敗したテストのみ 再実行されます 成功しているテストを 再実行しないので時間を節約できます。 多くのプロジェクトでは XCTest APIベースの大規模なテストスイートがあります Swift 6.4ではXCTestの アサーション失敗が問題として報告されます Swift Testingから 呼び出された場合です。 これによりSwift Testingへの 移行が容易になります 移行中にテストカバレッジが 失われる心配がありません。 相互運用性は 逆方向でも機能します Swift Testingの#expectマクロ等は XCTestCaseからも機能します。 Swift Testingでヘルパー APIを 構築でき一貫した動作が得られます XCTestとSwift Testingの どちらから呼び出しても同様です。 既存のプロジェクトで 作業している場合 すでにSwift TestingからXCTestの アサーションを呼び出しているかもしれません またその逆も同様です。 この移行を容易にするために これらの問題はデフォルトで 警告として報告されます。 Xcodeのビルド設定で テスト失敗に昇格させることもできます。 Swift Testingの相互運用性や 移行戦略の詳細については "Migrate to Swift Testing"を ご覧ください。

    昨年 Subprocessパッケージを 発表しました サブプロセスを起動するための モダンなAPIを含んでいます。 今年 Subprocess 1.0を リリースします 実際の使用からいただいた フィードバックを取り込みました。 API改善には 簡略化された実行タイプが含まれます 改善されたエラー処理と 出力ストリーミング用の便利なAPIです。 クロスプラットフォームサポートも 大幅に向上しました プラットフォーム固有のプロセス ディスクリプタや終了ステータスを含みます 各プラットフォームのセマンティクスを より正確に反映します。 Subprocess 1.0の 改善されたAPIの例です。 runメソッドを呼び出して サブプロセスを起動する場合 標準出力と標準エラーの ストリームは AsyncBufferSequenceとして 実行オブジェクトに含められます。

    このモデルでは各ストリームが 1度だけ作成されることが保証されます。 AsyncBufferSequenceの 新しいstrings()メソッドで サブプロセスの出力を 行ごとに読み取れます。 このAPIは書記素クラスターの 境界を遵守します マルチバイト文字が 分割される心配がありません。 最後にFoundationの 改善について見ていきましょう。 ProgressManagerは Foundationの新しい進捗報告タイプです。 async/awaitスタイルの並行処理と うまく連携するよう設計されており 進捗の構成と報告を 明確に分離します 構造化されていて 追加メタデータを添付するための 型安全なメカニズムを提供します。 2年前にSwift-Foundationを 発表しました Foundationを安全で一貫した Swiftで書かれた クロスプラットフォームコードベースに移行する取り組みです。 今年もその取り組みを続け 何十年ものObjective-Cを モダンなSwiftに置き換えています。 今年はDataの多くの部分を 最新化しました 全体的な改善につながりました spanアクセス、等価確認、 イテレーション、変更処理が高速化されました。 AppleプラットフォームでのDataと NSData間のブリッジも高速化されました。 NSURLとCFURLが統一され 単一のSwift実装になりました。 Swiftを活用することでこれらの型は 高速化しメモリ使用量も削減されます。 Foundationのような大規模で 成熟したライブラリの移行は Swiftの言語相互運用性があるから こそ可能です。 Swiftで全く新しいAPIを追加したり 移行することもできます APIサーフェスを変えずに 既存APIの実装をSwiftに移行できます。 言語の境界を越えることに加えて 実際の多くのプロジェクトは サービス、デバイス、Webコンポーネントに広がります クロスプラットフォームの クライアントなど多岐にわたります。

    AppleではOSのあらゆる部分で Swiftを使用しています 天気のようなアプリや リアルタイム通話スパム検出などのサービスで カーネル自体から ファームウェアの最下層まで使用しています。 Swiftはあらゆる場面で 使える言語として設計されており ソフトウェアスタックの あらゆる層に対応します。 既存のソフトウェアシステムで より使いやすくするために Swift 6.4は言語の 相互運用性を拡張し クロスプラットフォームIDEサポートを改善し より安全かつ容易に SwiftコードをWebや 組み込みデバイス環境に持ち込めます。

    これまでCをSwiftに 簡単にインポートできました。 Swift 6.4ではSwiftで書いた関数を Cに公開できるようになりました。 @objc属性を見たり使ったりした ことがあるかもしれません Objective-CからSwiftへの アプリ移行時にです。 @C属性も同じように機能しますが C向けです。 @C属性はCと互換性のある型を 操作する関数に適用します。 CからSwiftにインポートできる型は SwiftからCにエクスポートする 関数でも使用できます 例えば整数 ポインタ、インポートしたCの構造体、 raw整数値型の列挙型などです。 コンパイラは誤った型の 受け渡しを防ぎます Cと非互換な型の場合です。 @C属性の実際の動作を 見てみましょう。 ロケット打ち上げを スケジュールするアプリを開発しています。 打ち上げウィンドウを 追跡するコードに注目します。 現在Cで書かれていますが メモリ安全性とデベロッパエルゴノミクスの 向上のためSwiftに移行しています。 Swift 6.4の新機能を使って アプリのC部分を 書き換えましょう。 現在ヘッダーに 2つの関数が宣言されています 1つは打ち上げウィンドウの 長さを取得するもの もう1つは複数の打ち上げウィンドウで 費やした合計時間を計算するものです 発射台の稼働率を 計算できます。 Cの実装を置き換えることから 始めましょう 打ち上げウィンドウの長さを 計算する関数の実装です。 @cと@implementation属性を 組み合わせて使うことで C宣言を作成せずに C関数を実装できます 元のヘッダーファイルに すでに存在しているためです。 次に計算する関数の 実装を提供します 複数の打ち上げウィンドウでの 合計滞在時間を計算します。 Swiftで実装する際は 関数がそのままインポートされます。 型をネイティブのSwift型に 変換できます SwiftのエルゴノミクスでC関数を 再実装できます。 セーフinterop機能は関数呼び出し時に 安全なラッパーを提供します 配列とカウントを別々に渡す代わりに spanを渡せます。 書きやすく安全です! 作業中に 打ち上げウィンドウの平均長を 取得する新しい関数を追加したいと思います。 ここでは@implementation属性は 使用しません 元のCヘッダーに 関数が宣言されていないためです。 Swiftコンパイラは適切な関数宣言を 生成されたCに出力します interopヘッダーに代わりに出力するため Cコードから新しい関数を呼び出せます。 SwiftはSwift SpanをCに 自動的にブリッジします。 また Swift C++相互運用性でも SwiftとC++ 20のspanをブリッジできます。 この宣言はspanでSwiftに インポートされ直接渡せます。

    相互運用性が重要です 他の言語で書かれた 既存コードベースへのSwift導入に。 Swift-JavaはSwiftとJava間の 相互運用を実現するパッケージです。 JavaからasyncやthrowingのSwift関数を 呼び出せるようになりました。 ジェネリクスシステムの より多くの機能をサポートします 制約付きextensionなど JavaクラスをSwiftプロトコルに 準拠させることも含みます。 これらすべての改善により JavaやKotlinからSwiftコードを Androidでも自然に呼び出せます。 swift.orgからAndroid向け公式 Swift SDKをダウンロードできます。 VSCode向けSwift拡張の 最新バージョンが Swiftlyとの新しい連携機能を 追加しました エディタからswift.orgの ツールチェーンを簡単にインストールできます。 これにより常にすべての プラットフォームに適したツールチェーンを持てます すぐに利用できます。 昨年 Swift拡張を Visual Studioマーケットプレイスに追加しました。

    今年はOpenVSX マーケットプレイスにも追加しました 統合されたSwiftエクスペリエンスを 新しいエディタで利用できるようになります VSCodium、Cursor、Kiro、 Antigravityなどです。 プラグインの最新バージョンで Swiftの開始がより簡単になりました Swiftのインストールを 案内するチェックリストがあります 新しいプロジェクトの作成、 コードの実行 テストの設定、 ドキュメントの生成が含まれます。 Swiftlyがインストールされていれば ツールチェーンの管理を助けます。 ナイトリーツールチェーンを インストールしています Web Assembly向けの 新しい言語機能を試すためです 組み込みプラットフォームも含みます。 インストールしたオープンソースの ツールチェーンはWasmにコンパイルできます。

    SwiftのWasmサポートで ネイティブアプリと同じ言語で 書けるということです バックエンドWebサーバーも フロントエンドも。 JavaScriptの相互運用性の改善を 見ていきましょう オープンソースプロジェクトの JavaScriptKitからの成果です。 SwiftとJavaScript間のブリッジは 多くの動的ルックアップが必要でした 型が一致することを 期待していました。 JavaScriptKitの最新の取り組みで 言語間のブリッジが より安全かつ高速になりました。 コードはネイティブSwiftのように 見えますが JavaScriptを通じて WebGLを呼び出しています。

    人気のメモアプリGoodnotesは ネイティブiOSアプリに加えて Webベースのインターフェースを実装しました。 コアアプリを別の言語に移行するコスト バグの修正と2つのコードベースの 維持コストが大きすぎました。 既存の実績あるSwiftコードを 活用しました Wasmを使ってWeb向けに コンパイルしました。 JavaScriptKitの改善により ベンチマーク結果では セーフブリッジが動的ブリッジより 35〜40倍高速であることが判明しました。 SwiftのWasmサポートで ネイティブiOSアプリで動く Swiftコードを持ち出せます Webアプリの一部として 実行できます。 ネイティブアプリとは異なり サイト訪問のたびに 各デバイスにコードを送る必要があります。 CDNが助けになりますが 大きなバイナリは自分とユーザーの データをすぐに消費します。 これによりサイズが 以前にも増して重要になっています。

    Embedded Swiftでは より制約のある環境でも Swiftのエルゴノミクスを活用できます。 言語を絞り込んで 適合させましたが こうした環境でのSwiftの使われ方を 学んでいく中で 利用可能な言語サブセットを 拡大しています。 Embedded Swiftで existential型をサポートするようになりました。 プロトコルに準拠した 複数の型を扱えます 配列に格納したり 関数に渡したりできます。 エラー型が分かっているとき typed throwsは優れていますが 特定のエラー型に 制限されます。 existential型を処理する 同じ基盤メカニズムを使って Embedded Swiftで untyped throwsをサポートするようになりました。 デバッガは変数を表示するために 型レイアウトの追加メタデータが必要です。 バイナリサイズを小さく保つために Embedded Swiftはそのデータを バイナリ自体に含めません。 さらに多くの組み込みシステムでは コアダンプのみが残ります プログラムがクラッシュした時の メモリ状態です ライブプロセスの デバッグさえできません。 Swift 6.4は必要なメタデータを DWARFデバッグ情報に保存します バイナリサイズを小さく保ちながら Embedded Swiftのコアダンプの デバッグ体験を大幅に向上させます。 これらは今年行った 改善のほんの一部です フルSwiftとEmbedded Swiftの ギャップを縮めています。 組み込みプラットフォームで動く Swiftのサブセットは拡大していますが まだ言語の サブセットです。 EmbeddedRestrictionsの警告グループの 診断が言語機能を識別します 組み込みコンテキストで 使用できないものを。 組み込みとフルSwiftの両方を サポートするライブラリで作業する場合 公開する必要がある 関数がある場合があります 組み込みコンテキストで 利用できない機能を使うものです。 先ほどBeccaが紹介した @diagnose属性を使うと これらの診断を 制御できます。 組み込みコードは非常に 制約されたハードウェア環境で動きます。 そのため毎クロックサイクルを 最大限に活用することが重要です。 BeccaがSwiftコードから パフォーマンスを引き出す方法をお伝えします。

    Swiftは優れたパフォーマンスを 持つよう設計されています 最もシンプルで 表現力豊かな ロジックの実装でも。 しかし多くの計算を行う場合や 組み込みシステムのような 制約された環境では コードを少し複雑にすることが 価値ある場合があります 重要な場面で わずかな改善を引き出すために。 通常これらの高度な パフォーマンス機能は不要ですが 必要な時には 役立ちます。

    今年取り組んだ2つの 領域に注目します オプティマイザの判断を 明示的に制御することと 不要なコピーを安全に防ぐための 所有権システムの拡張です。 Swiftコンパイラの オプティマイザは コードを高速化するために 数十の技術を適用します しかし最も強力なものの中には 誤って適用すると 逆効果になるものもあります。 特定の状況に合わせて コードを複製するものです しかしカスタマイズが効果的でないと プログラムは 小さく高速になるどころか 大きく低速になります。 たとえば コンパイラが行う最も重要な 最適化の1つがインライン化です 関数呼び出しを 実装に置き換えます そして特定の呼び出し元に合わせて その実装を最適化します。 インライン化が効果的であれば 同じ結果を少ない処理で得られますが そうでない場合は バイナリが大きくなるだけで 高速化はしません。 それを防ぐために オプティマイザは関数と 呼び出し元を分析して インライン化が効果的かどうかを 判断します しかし時に 誤った判断をすることがあります そのため強制的に指定する 方法が必要です。

    Swiftには以前から @inline(never)属性があります インライン化を 完全に禁止するもので インライン化が決して効果的でないと 分かっている場合に有用です。 Swift 6.4では対応する @inline(always)属性が追加されました コンパイラに インライン化を強制します オプティマイザが 効果的かどうか確信できない場合でも。 ただし時に それができない場合もあります オーバーライドされる可能性のある オブジェクトメソッドを呼び出す場合などです クラスメソッドにはfinalと @inline(always)の併用を検討してください。 もう一つの重要な最適化が 特殊化(specialization)です 特定の具体的な型のために ジェネリック関数を複製します ジェネリックのオーバーヘッドを削減し さらなる最適化を実現します。 関数の特殊化が 効果を発揮するのは オプティマイザがその型での 使用を認識している場合のみです しかし時にライブラリでは 特に コンパイラは関数がどのように 使われるかを見ることができません。 Swift 6.3では@specialized属性が 導入されました これを直接制御するために。 属性の中で ジェネリックパラメータの 一部または全部を制限するwhere句を書き Swiftはその制約を持つ 特殊化された関数のバージョンを生成します その制約で。 遅いジェネリックコードがあって 1〜2つの特定の型で 頻繁に使われる場合 Swiftにその型を 優先するよう伝えられます。 しかしパフォーマンスチューニングで 最大の改善は 所有権システムに 対するものです。 何を行ったかを理解するために 既存のものを振り返りましょう。 Swiftの多くのパフォーマンス問題は 不要なデータのコピーに起因します。 あるデータが一方にあり 別の場所でも必要です そのためデータを新しい ストレージにコピーします。 コンポーネントが大きい場合もあります アプリのモデル層やビュー層のように 小さい場合もあります forループのin両側の 2つの変数のように しかし基本的なパターンは 同じです。 コピーによる遅延を解決するには あることを認識する必要があります 特定の状況では コピーが不要だということです。 ストレージが割り当てられたまま であることが分かっていれば 両コンポーネントがSwiftの 排他性ルールに従うなら 双方がアクセスできるデータを 変更しないため データをコピーする必要はありません 既存のストレージへの アクセスを許可するだけです。 コピーを避ける最もシンプルな方法は データをオブジェクトに入れることです そのオブジェクトを 別のコンポーネントに渡します。 これで十分な場合が多いですが 問題を完全には解消しません。 オブジェクトは 参照カウント方式のため オブジェクトの受け渡しで 参照カウントが変わります。 解放と保持のオーバーヘッドは 大きな値のコピーより少ないですが 最もパフォーマンスに敏感なコードでは まだ遅すぎる場合があります。 オブジェクトが使えない場合 代わりにUnsafePointerを ストレージに渡すしかありませんでした。 しかしその名の通り UnsafePointerは安全ではありません。 このようなストレージ共有が安全なのは 両コンポーネントが 特定のルールに従っているためですが コンパイラはそのルールを知らず 確認できません 各側がその取り決めを 守るかどうかを。 Component 1が変更しないはずの データを変更するかもしれません Component 2が使用中に ストレージを解放するかもしれません。 C言語のような メモリ安全性のない世界に戻ります。

    そこで数年前により良い解決策に 取り組み始めました。 ストレージを安全に共有するための 保証の集合をborrowとして規定しました。 Component 2がストレージを 借用している間は 両コンポーネントは読み取りのみ 書き込みはできません。 Component 2が先に ストレージの使用を終える必要があります そうすると Component 1が完全制御を取り戻します。 mutationも同様ですが 他のコンポーネントはストレージへの アクセスを完全にブロックされます。 途中更新データの読み取りや 動作の不一致を防ぎます 他のコンポーネントが変更を 書き戻すタイミングに関わらずです。 借用またはmutationのどちらでも コンパイル時に検証できます 両コンポーネントが ルールに従っているかどうかを。

    しかし私たちの目標は これらの高度なユースケースをサポートしながら 通常のSwiftコードの 書き方に影響を与えないことです。 これにより所有権機能の 慎重なインクリメンタル設計が必要でした。 数年にわたるプロセスで まだ完了していませんが 今年さらに 数歩前進しました。 たとえばEquatable、Comparable、 Hashableプロトコルが noncopyable型でも 使えるようになりました。 EquatableとComparableは non-escapable型でも使えます。 パフォーマンスと安全性のために 調整された型が 最も普遍的な機能の 一部を活用できます 通常のSwift型が持つものです。 Associated typeも non-copyableやnon-escapableにできるようになりました。 これにより強力な 新機能が開かれます 高パフォーマンスな プロトコル駆動開発に向けて ここに見られる Iterableプロトコルのようにです。 element型はnon-copyableで iterator型はnon-copyableかつ non-escapableです。 もちろんcopyableや escapable型を使えないわけではありません プロトコルが それを要求しないということです。 ところでこのIterableは とても便利そうです。 実際にあったらいいと思いませんか 朗報です、本当にあります!

    Swift 6.4のforループは 新しいIterableプロトコルをサポートします。 皆さんご存知の Sequenceプロトコルは シーケンスから要素を コピーして取り出します Iterableプロトコルでは forループが要素を借用できます。 non-copyable要素でも 動作します また参照カウントを 実行する必要もありません オブジェクトや copy-on-write型で動作する場合でも。 さらにループ中に エラーをスローすることも可能で async Sequenceと 同様です。 ただし借用と同様に 排他性チェックにより Iterableを変更できません ループ中は 必ずしも悪いことではありませんが Sequenceでは パフォーマンスの落とし穴でした。 この動作の違いから forループはSequenceプロトコルを 優先的に使用します なければIterableに フォールバックします。 Sequenceと同様に Iterableはイテレータを作成して動作します forループが要素を 取得するためです。 ただしSequenceと異なり 要素をバッチで取得します。 forループはイテレータに 要素のスパンを要求して 1つずつ処理します。 次のスパンを要求して それも処理します。 要素がなくなると 空のスパンを返します forループが 終了します。 このバッチ設計により ループの効率が大幅に向上します すべてを1つの大きなスパンで 返せる型に特に有効です。 Swift 6.4はアクセサにも 大幅な改善をもたらします。 重要性を理解するために このUniqueBox structを見てみましょう。 大きな値へのポインタを 自動的に管理します アクセスのための computed propertyを提供します。 残念ながら現状の 実装では このプロパティに深刻な パフォーマンス問題があります。 理由を見てみましょう。 UniqueBoxに256個のIntの InlineArrayを入れるとしましょう。 InlineArrayはインラインなので 64ビットデバイスでは 2キロバイトのstructになります。 頻繁にコピーしたくない サイズですね! getとsetはデータをコピーして 動作するので問題です。 配列の1つのIntを変更するには 全体をコピーして取り出し また戻す必要があります。 パフォーマンスの 改善にはなりません! 幸いより良い選択肢が 利用できるようになりました getとsetから borrowとmutateに切り替えられます。 新しいborrowアクセサは共有ストレージへの 読み取り専用アクセスを提供します コピーなしで mutateアクセサは インプレース修正の排他アクセスを提供します。 切り替えると Swiftは何もコピーせずに 元の配列の要素を変更できます。 さらにボーナスとして 新しいアクセサにより UniqueBoxはnon-copyable値も扱えます。 borrowとmutateアクセサは パフォーマンスと表現力の両方に役立ちます 皆さんに使っていただける状態になり 嬉しく思います。 ところでこのUniqueBoxも とても便利そうです。 実際にあったらいいと… 分かりました 分かりました そのくだりはもうしません。

    UniqueBoxは実際の型で 標準ライブラリに追加されました。 unsafeなコードを書かずに済む 他の新しいAPIもあります Unique Arrayは通常のSwift Arrayと よく似ていますが non-copyableである点が 異なります。 non-copyable要素を 格納でき 固定サイズに縛られずに 参照カウントのオーバーヘッドを回避できます。 withTemporaryAllocation関数は OutputSpanを使います UnsafeMutableBufferPointerの代わりに 一時メモリを安全に処理します。 Continuation型はコンパイル時に 1度だけresumeされることを確認します CheckedContinuationより さらに安全で UnsafeContinuationと同様の 効率を持ちます。 さらに紹介したい 2つの型のペアがあります 既存のAPIの改善版ではなく 言語に新しい機能を もたらします。 Refは Spanに似ていますが 多値でなく単一値用です。 借用またはmutationの コンテナのようなものです 変数に格納でき 関数から渡したり返したり ジェネリック型でも使用できます。 ストレージを借用して読み取りアクセスから Ref型のインスタンスを作れます または書き込みアクセスから MutableRef型のインスタンスを作れます プレフィックスアンパサンドを 使用して。 これらの型でこれまで 書けなかった新しいAPIを作れます プロパティのMutableRefを 返すメソッドのように パフォーマンスの問題にも 対処できます。 たとえばこの updateCount関数を見てみましょう。 インクリメントが必要なたびに ディクショナリキーを検索します キーは常に同じであっても。 通常このような繰り返し作業を ループの外に出したいはずです 1度だけ実行するために しかしこれまでは ディクショナリルックアップを行い しばらく保持し続ける唯一の方法は ループを関数に移動して ルックアップをinoutで渡すことでした。 かなりマニアックな テクニックです!

    MutableRefでより良い 方法が得られます。 ディクショナリルックアップから 1度MutableRefを作成して ループ開始前に ディクショナリエントリを変更したい時に 使用します。 Refはnon-escapableなので Swiftはアクセスが終了することを知っています 変数がスコープを 外れた時に。 これらの新しい所有権機能がすべて 組み合わさって 最もパフォーマンスに敏感なコードの 高速化が今まで以上に安全で簡単になります。 所有権システムだけが 進行中のものではありません。 EvanにSwiftの将来について 伝えてもらいましょう。

    今日紹介した機能は オープンソースで開発され 全体的なエクスペリエンスを向上させています Apple OS群、Linux、 Windowsなど様々なプラットフォームで。 オープンソースコミュニティで 進行中のさらなる将来の開発を紹介します 参加することも できます。 昨年 XcodeのビルドシステムSwift Buildを オープンソース化すると発表しました。 Swift BuildはSwift Package Managerの デフォルトビルドシステムバックエンドになりました Swiftパッケージビルドの 一貫性が向上します Xcodeでの体験と 合わせて。 増加するワークグループに加わったのは ビルド・パッケージングワークグループです Swiftコミュニティの ビルドとパッケージングのニーズに対応します。 ネットワーキングワークグループは 次世代のクロスプラットフォーム ネットワークAPIを設計しています。 WindowsワークグループはWindowsでの Swiftエクスペリエンスを向上させています。 今年 AndroidワークグループはSwift 6.3で Android向けSwift SDKを初リリースしました。 AndroidとiOSアプリ間で Swiftコードの共有が可能になりました。 Swiftエコシステムの 開発に参加してみたい場合は forums.swift.orgの Swiftフォーラムにご参加ください。 皆さんの貴重な フィードバックをお待ちしています。 Swiftの新機能について ご覧いただきありがとうございます。 バグレポートの提出 プルリクエスト、イベント参加、 フォーラムへの参加 皆さんの貢献が Swiftの将来を形作ります プログラミングをより安全で 誰もが取り組みやすくするために。 ありがとうございました。

    • 1:12 - Better Swift Concurrency diagnostics (catching in the task)

      Task {
          do {
              try lander.fly(to: moon)
          }
          catch {
              lander.abort()
          }
      }
    • 1:21 - Better Swift Concurrency diagnostics (saving the task for later)

      let landingTask = Task {
          try lander.fly(to: moon)
      }
      
      defer {
          await orbiter.rendezvous(with: lander)
      }
      
      try await orbiter.justHangOut(waitingFor: landingTask)
    • 1:27 - Better 'Sendable' conformances

      final class Spacecraft: Sendable {
          ...
          weak let dockedAt: SpaceStation?
          ...
      }
      
      class Mission: ~Sendable { ... }
      
      class CrewedMission: Mission, @unchecked Sendable { ... }
    • 1:48 - More accessible memberwise initializers

      struct Briefing {
          internal var topic: String
          internal var scheduledAt: Date
          private  var attendees: [Person] = []
      }
      
      // Generated memberwise initializers:
      // extension Briefing {
      //     private init(topic: String, scheduledAt: Date, attendees: [Person] = []) { 
      //          self.topic = topic
      //          self.scheduledAt = scheduledAt
      //          self.attendees = attendees
      //     }
      // 
      //     internal init(topic: String, scheduledAt: Date) {
      //          self.topic = topic
      //          self.scheduledAt = scheduledAt
      //          self.attendees = []
      //     }
      // }
    • 2:03 - 'anyAppleOS' availability (before)

      extension Mission {
          @available(macOS 27, iOS 27, watchOS 27, tvOS 27, visionOS 27, *)
          func showStatus() { ... }
      
          @available(macOS 27, iOS 27, watchOS 27, visionOS 27, *)
          @available(tvOS, unavailable)
          func launch() { ... }
        
          #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(visionOS)
          func makeLiveActivityWidget() -> some Widget { ... }
          #endif
      }
    • 2:17 - 'anyAppleOS' availability (after)

      extension Mission {
          @available(anyAppleOS 27, *)
          func showStatus() { ... }
      
          @available(anyAppleOS 27, *)
          @available(tvOS, unavailable)
          func launch() { ... }
        
          #if os(anyAppleOS)
          func makeLiveActivityWidget() -> some Widget { ... }
          #endif
      }
    • 2:40 - Controlling warnings with '@diagnose'

      @diagnose(DeprecatedDeclaration, as: ignored, reason: "Flying with surplus hardware")
      func makeApolloSoyuzMission() -> Mission {
          CrewedMission(
              rocket: makeSaturnIRocket(),
              payload: makeApolloCSM(),
              crew: [.daniellePoole, .nathanMorrison]
          )
      }
      
      @diagnose(StrictMemorySafety, as: warning)
      func uplinkCommand(from receiver: inout Receiver, to computer: inout Computer) {
          let commandSize = receiver.receiveInt()
          receiver.withReceivedData(byteCount: commandSize) {
              computer.receiveUplinkedCommand($0)
          }
      }
      
      @diagnose(ErrorInFutureSwiftVersion, as: error)
      func fetchPosition() -> (x: Double, y: Double, z: Double) {
          return self.rotation
      }
    • 3:47 - Clarifying code with module selectors

      import Rocket
      import GiftShopToys
      
      let rocket1 = SaturnV()            // could mean `Rocket::SaturnV` or `GiftShopToys::SaturnV`
      let rocket2 = Rocket.SaturnV()     // prefers `Rocket::Rocket.SaturnV`
      let rocket3 = Rocket::SaturnV()    // correctly finds `Rocket::SaturnV`
    • 5:00 - Clarifying code with module selectors (module selectors work on members, too)

      //
      // Module Chemistry
      //
      
      public protocol Flammable { ... }
      
      extension Flammable {
          /// Set `self` on fire.
          public func fire() { ... }
      }
      
      //
      // Module HumanResources
      //
      
      import Chemistry
      
      public protocol Employee { ... }
      
      extension Employee {
          /// Remove `self` from job.
          public func fire() { ... }
      }
      
      public class LaunchPadTechnician: Employee, Flammable { ... }
      
      //
      // Module main
      //
      
      import HumanResources
      import Chemistry
      
      let launchPadTechnician = LaunchPadTechnician(...)
      
      launchPadTechnician.HumanResources::fire()
    • 6:26 - Task cancellation

      // Radio for help
      
      extension Radio {
        func send(_ data: [UInt8] {
          if Task.isCancelled { return }
          // ...
        }
      }
        
      extension EmergencyTransponder {
        func sendSOS() {
          radio.send(makeSOSPacket())
        }
      }
    • 6:40 - Task cancellation shield

      // Radio for help
      
      extension Radio {
        func send(_ data: [UInt8] {
          if Task.isCancelled { return }
          // ...
        }
      }
        
      extension EmergencyTransponder {
        func sendSOS() {
          withTaskCancellationShield {
          	radio.send(makeSOSPacket())
          }
        }
      }
    • 6:53 - Constructing a new dictionary

      // Map values with keys
      
      func makeCalendarDisplayNames(for missions: [Mission: LaunchWindow]) -> [Mission: String] {
          let new: [Mission: String] = .init(
              uniqueKeysWithValues: missions.lazy.map { mission, launchWindow in
                  (mission, makeDisplayName(for: mission, in: launchWindow))
              }
          )
          return new
      }
    • 7:06 - Dictionary.mapKeyedValues

      // Map values with keys
      
      func makeCalendarDisplayNames(for missions: [Mission: LaunchWindow]) -> [Mission: String] {
          missions.mapKeyedValues { mission, launchWindow in
              makeDisplayName(for: mission, in: launchWindow)
          }
      }
    • 7:14 - The new FilePath type

      // FilePath handling macOS-named resources
      
      var path: FilePath = "/var/www/static"
      path.components.append("WWDC")
      print(path.components)
      // [ "var", "www", "static", "WWDC" ]
      
      var path: FilePath = "/var/www/static/..namedresource/rsrc"
      print(path.components)
      // [ "var", "www", "static" ]
    • 7:41 - Issue Severity

      // Issue severity
      
      @Test(arguments: allRockets)
      func testBurn(rocket: Rocket) throws {
          rocket.burn(for: .seconds(150))
          let remaining = rocket.propellantKg / rocket.totalPropellantKg
      
          if remaining < 0.10 {
              Issue.record(
                  "\(rocket.name) remaining fuel is below 10% reserve target",
                  severity: .warning
              )
          }
      
          #expect(remaining > 0.02, "\(rocket.name) propellant critically low - abort")
      }
    • 7:52 - Test Cancellation

      // Test Cancellation
      
      @Test(arguments: allRockets)
      func testBurn(rocket: Rocket) throws {
          // solid-fuel rocket engines can't be stopped
          if rocket.engineType == .solid {
              try Test.cancel("\(rocket.name) has solid fuel")
          }
       
          rocket.burn(for: .seconds(150))
          let remaining = rocket.propellantKg / rocket.totalPropellantKg
      
          if remaining < 0.10 {
              Issue.record(
                  "\(rocket.name) remaining fuel is below 10% reserve target",
                  severity: .warning
              )
          }
      
          #expect(remaining > 0.02, "\(rocket.name) propellant critically low - abort")
      }
    • 8:34 - XCTest interoperability: Using XCTest from Swift Testing

      // XCTest interoperability: Using XCTest from Swift Testing
      
      func checkedTransmitAndReceive(on radio: Radio,
                                     packet: Packet,
                                     expectedByteCount: Int) throws -> [UInt8] {
          try radio.transmit(bytes: packet.data)
          let bytes = try radio.receive()
          XCTAssertEqual(bytes.count, expectedByteCount)
          return bytes
      }
      
      @Test
      func pingTest() throws {
          let radio = Radio()
          let bytes = try checkedTransmitAndReceive(on: radio, packet: .ping, expectedByteCount: 8)
          #expect(bytes == [0x00, 0x00, 0xf0, 0x37, 0x0f, 0xc7, 0x00, 0x01])
      }
    • 8:48 - XCTest interoperability: Using Swift Testing from XCTest

      // XCTest interoperability: Using Swift Testing from XCTest
      
      class RadioTests: XCTestCase {
          func testPingPacketTransmission() {
              let radio = Radio()
              let bytes = try checkedTransmitAndReceive(on: radio,
                                                        packet: .ping,
                                                        expectedByteCount: 8)
      
              #expect(bytes == [0x00, 0x00, 0xf0, 0x36, 0x0f, 0xc7, 0x00, 0x02])
          }
      }
    • 10:01 - Subprocess Output Stream

      // Subprocess output streaming
      
      let result = try await Subprocess.run(.name("ls"),
                                            input: .none,
                                            output: .sequence,
                                            error: .string(limit:4096)) { execution in
      		execution.standardOtput.strings().filter { $0.hasSuffix(".obj") }
      }
      
      for try await objectFiles in result.closureOutput {
        	print("Object file: \(objectFile)")
      }
    • 10:37 - Progress Manager - Concurrency

      // Progress reporting - Concurrency
      
      let manager = ProgressManager(totalCount: 100)
      try await rocket.launch(mission.subprogress(assigningCount: 100))
      
      extension Rocket {
          func launch(_ progress: consuming Subprogress? = nil) async throws {
              let stage = progress?.start(totalCount: 3)
              try await ignite(); stage?.complete(count: 1)
              try await liftoff(); stage?.complete(count: 1)
              try await stageSeparation(); stage?.complete(count: 1)
          }
      }
    • 10:37 - Progress Manager - progress reporting

      // Progress reporting - progress reporting
      
      let manager = ProgressManager(totalCount: 100)
      try await rocket.launch(mission.subprogress(assigningCount: 100))
      
      Task {
          for await update in Observations({ mission.fractionCompleted }) {
              print("🚀 Mission \(Int(update * 100))%")
          }
      }
    • 10:37 - Progress reporting - metadata

      // Progress reporting - metadata
      
      extension Rocket {
          func ascend(_ progress: consuming Subprogress) async throws {
              let stage = progress.start(totalCount: 3)
              stage.detlaV = 3_400; try await burn(); stage.complete(count: 1)
              stage.detlaV = 2_100; try await stageSeparation(); stage.complete(count: 1)
              stage.detlaV = 1_800; try await coast(); stage.complete(count: 1)
          }
      }
      
      print("Δv to orbit: \(mission.summary(of: \.deltaV)) m/s")
    • 20:56 - Directly control inlining (source code)

      func histogram<Values>(of values: Values) -> [256 of Int] where Values: Sequence<UInt8> {
          var result = makeInts(randomized: false)
        
          for value in values {
              result[Int(value)] += 1
          }
        
          return result
      }
      
      func makeInts(randomized: Bool) -> [256 of Int] {
          if randomized {
              InlineArray { _ in Int.random(in: (.min)...(.max)) }
          } else {
              InlineArray(repeating: 0)
          }
      }
    • 21:01 - Directly control inlining (inlined, but not optimized)

      func histogram<Values>(of values: Values) -> [256 of Int] where Values: Sequence<UInt8> {
          var result = if false {                                                  //
                           InlineArray { _ in Int.random(in: (.min)...(.max)) }    //
                       } else {                                                    // Inlined code
                           InlineArray(repeating: 0)                               //
                       }                                                           //
      
         for value in values {
              result[Int(value)] += 1
          }
          return result
      }
      
      func makeInts(randomized: Bool) -> [256 of Int] {
          if randomized {
              InlineArray { _ in Int.random(in: (.min)...(.max)) }
          } else {
              InlineArray(repeating: 0)
          }
      }
    • 21:07 - Directly control inlining (inlined and optimized)

      func histogram<Values>(of values: Values) -> [256 of Int] where Values: Sequence<UInt8> {
          var result = InlineArray(repeating: 0)    // Inlined and optimized code
      
         for value in values {
              result[Int(value)] += 1
          }
          return result
      }
      
      func makeInts(randomized: Bool) -> [256 of Int] {
          if randomized {
              InlineArray { _ in Int.random(in: (.min)...(.max)) }
          } else {
              InlineArray(repeating: 0)
          }
      }
    • 21:30 - Directly control inlining (preventing inlining)

      @inline(never)
      func makeInts(randomized: Bool) -> [256 of Int] {
          if randomized {
              InlineArray { _ in Int.random(in: (.min)...(.max)) }
          } else {
              InlineArray(repeating: 0)
          }
      }
    • 21:39 - Directly control inlining (forcing inlining)

      @inline(always)
      func makeInts(randomized: Bool) -> [256 of Int] {
          if randomized {
              InlineArray { _ in Int.random(in: (.min)...(.max)) }
          } else {
              InlineArray(repeating: 0)
          }
      }
    • 21:55 - Making generic functions faster with '@specialized'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

      func histogram<Values>(of values: Values) -> [256 of Int] where Values: Sequence<UInt8> {
          var result = makeInts(randomized: false)
        
          for value in values {
              result[Int(value)] += 1
          }
        
          return result
      }
      
      // Note: Specialized function doesn't actually have a directly callable name.
      func `histogram of [UInt8]`(of values: [UInt8]) -> [256 of Int] {    //
          var result = makeInts(randomized: false)                         //
                                                                           //
          for value in values {                                            //
              result[Int(value)] += 1                                      // Specialized code
          }                                                                //
                                                                           //
          return result                                                    //
      }                                                                    //
    • 22:17 - Making generic functions faster with '@specialized'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ (explicitly requesting specialization)

      @specialized(where Values == [UInt8])
      func histogram<Values>(of values: Values) -> [256 of Int] where Values: Sequence<UInt8> {
          var result = makeInts(randomized: false)
        
          for value in values {
              result[Int(value)] += 1
          }
        
          return result
      }
      
      // Note: Specialized function doesn't actually have a directly callable name.
      func `histogram of [UInt8]`(of values: [UInt8]) -> [256 of Int] {    //
          var result = makeInts(randomized: false)                         //
                                                                           //
          for value in values {                                            //
              result[Int(value)] += 1                                      // Specialized code
          }                                                                //
                                                                           //
          return result                                                    //
      }                                                                    //
    • 25:46 - Associated types can be '~Copyable' and '~Escapable'

      protocol Iterable<Element, Failure>: ~Copyable, ~Escapable {
          associatedtype Element: ~Copyable
          associatedtype IterableIterator: IterableIteratorProtocol<Element, Failure>, ~Copyable, ~Escapable
          associatedtype Failure: Error = Never
      
          func makeIterableIterator() -> IterableIterator
        
          var underestimatedCount: Int { get }
      }
      
      protocol IterableIteratorProtocol<Element, Failure>: ~Copyable, ~Escapable {
          associatedtype Element: ~Copyable
          associatedtype Failure: Error = Never
      
          mutating func nextSpan(maximumCount: Int) throws(Failure) -> Span<Element>
        
          mutating func skip(by maximumOffset: Int) throws(Failure) -> Int
      }
    • 27:28 - The problem with existing accessors

      @safe public struct UniqueBox<Value>: ~Copyable {
          private let valuePointer: UnsafeMutablePointer<Value>
      
          public init(_ value: consuming Value) {
              valuePointer = UnsafeMutablePointer.allocate(capacity: 1)
              valuePointer.initialize(to: value)
          }
      
          public var value: Value {
              get { valuePointer.pointee }
              set { valuePointer.pointee = newValue }
          }
      
          deinit {
              valuePointer.deinitialize(count: 1)
              valuePointer.deallocate()
          }
      }
    • 28:19 - 'borrow' and 'mutate' accessors

      @safe public struct UniqueBox<Value: ~Copyable>: ~Copyable {
          private let valuePointer: UnsafeMutablePointer<Value>
      
          public init(_ value: consuming Value) {
              valuePointer = UnsafeMutablePointer.allocate(capacity: 1)
              valuePointer.initialize(to: value)
          }
      
          public var value: Value {
              borrow { valuePointer.pointee }
              mutate { &valuePointer.pointee }
          }
      
          deinit {
              valuePointer.deinitialize(count: 1)
              valuePointer.deallocate()
          }
      }
    • 30:14 - Using 'MutableRef' to eliminate repeated accesses (with un-hoisted access)

      func updateCount<Key: Hashable>(
          for key: Key,
          from sets: [Set<Key>],
          in counts: inout [Key: Int]
      ) {
          for set in sets {
              if set.contains(key) {
                  counts[key, default: 0] += 1
              }
          }
      }
    • 30:34 - Using 'MutableRef' to eliminate repeated accesses (hoisted by 'inout' parameter)

      func updateCount<Key: Hashable>(
          for key: Key,
          from sets: [Set<Key>],
          in counts: inout [Key: Int]
      ) {
          func updateCountImpl(count: inout Int) {
              for set in sets {
                  if set.contains(key) {
                      count += 1
                  }
              }
          }
          
          updateCountImpl(count: &counts[key, default: 0])
      }
    • 30:41 - Using 'MutableRef' to eliminate repeated accesses (hoisted by 'MutableRef')

      func updateCount<Key: Hashable>(
          for key: Key,
          from sets: [Set<Key>],
          in counts: inout [Key: Int]
      ) {
          var countRef = MutableRef(&counts[key, default: 0])
      
          for set in sets {
              if set.contains(key) {
                  countRef.value += 1
              }
          }
      }
    • 0:07 - Introduction
    • A preview of the session's four topics: language improvements, library updates, cross-platform support, and performance tuning in Swift 6.3 and 6.4.

    • 0:44 - Everyday Language Improvements
    • Quality-of-life changes land in Swift 6.4, including optional parentheses removal, concurrency task warnings, weak let, ~Sendable, and a new memberwise initializer.

    • 1:55 - anyAppleOS Availability
    • Swift now lets you condense multi-platform availability attributes into a single anyAppleOS condition, reducing boilerplate across iOS, macOS, watchOS, and more.

    • 3:02 - @diagnose Attribute
    • The new @diagnose attribute gives fine-grained control over warnings within a specific declaration, letting you suppress, enable, or promote them to errors.

    • 3:52 - Module Selectors (::)
    • Swift 6.3 introduces double-colon module selector syntax to unambiguously reference a type or member from a specific module when name conflicts arise.

    • 5:59 - Library Updates
    • Updates across four key libraries: the standard library, Swift Testing, Subprocess, and Foundation.

    • 6:16 - Standard Library
    • New additions include a task cancellation shield, mapKeyedValues for dictionaries, and a cross-platform FilePath type.

    • 7:31 - Swift Testing Updates
    • Swift Testing gains configurable issue severity, dynamic test cancellation, flaky test repetition, and improved two-way interoperability with XCTest.

    • 9:29 - Subprocess 1.0
    • Subprocess reaches 1.0 with a refined API, improved error handling, convenient line-by-line output streaming, and expanded cross-platform support.

    • 10:14 - Foundation
    • Foundation gains a new ProgressManager type and continues its Swift migration, with performance improvements to Data, NSURL, and CFURL.

    • 11:59 - Beyond Apple Platforms
    • Swift 6.4 extends language interoperability and broadens its reach to new environments including web, Android, and embedded devices.

    • 12:35 - Swift–C Interoperability (@C attribute)
    • The new @C attribute lets you expose Swift functions directly to C, enabling safe, incremental migration of C codebases to Swift.

    • 15:09 - Swift-Java
    • The Swift-Java package now supports async and throwing Swift functions from Java, constrained extensions, and conforming Java classes to Swift protocols.

    • 16:03 - Editor support
    • The Swift VSCode extension adds Swiftly integration for toolchain management and is now available on the OpenVSX marketplace for editors like Cursor and VSCodium.

    • 16:44 - WebAssembly (Wasm) & JavascriptKit
    • Swift can now compile to WebAssembly, with JavascriptKit improvements delivering up to 40x faster safe bridging between Swift and JavaScript.

    • 18:08 - Embedded Swift
    • Embedded Swift expands its language subset with existential types, untyped throws, and improved DWARF debug info for coredump debugging on constrained hardware.

    • 19:59 - Performance Tuning
    • Two areas of advanced performance work: explicit optimizer control and extensions to the ownership system to prevent unnecessary copying.

    • 21:29 - Optimizer Control: @inline(always) & @specialized
    • New @inline(always) and @specialized attributes give you direct control over the compiler's inlining and generic specialization decisions.

    • 24:29 - Ownership System & Noncopyable Types
    • Equatable, Comparable, Hashable, and associated types now work with noncopyable and non-escapable types, broadening the ownership system's reach.

    • 26:18 - Iterable Protocol & Borrow/Mutate Accessors
    • A new Iterable protocol enables efficient borrow-based for loops over noncopyable elements, while new borrow and mutate accessors eliminate costly copies in computed properties.

    • 28:57 - New Standard Library Types: UniqueBox, UniqueArray, Ref
    • The standard library gains UniqueBox, UniqueArray, Continuation, and the new Ref/MutableRef types for safe, high-performance ownership patterns.

    • 31:11 - The Future of Swift
    • Highlights open-source progress including Swift Build, new workgroups for build, networking, Windows, and Android, and an invitation to participate at forums.swift.org.

Developer Footer

  • ビデオ
  • WWDC26
  • Swiftの新機能
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • Apple Intelligence
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習とAI
    • オープンソース(英語)
    • セキュリティ
    • SafariとWeb(英語)
    メニューを開く メニューを閉じる
    • 英語ドキュメント(完全版)
    • 日本語ドキュメント(一部トピック)
    • チュートリアル
    • ダウンロード
    • フォーラム(英語)
    • ビデオ
    Open Menu Close Menu
    • サポートドキュメント
    • お問い合わせ
    • バグ報告
    • システム状況(英語)
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(英語)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(英語)
    • Mini Apps Partner Program
    • News Partner Program(英語)
    • Video Partner Program(英語)
    • セキュリティ報奨金プログラム(英語)
    • Security Research Device Program(英語)
    Open Menu Close Menu
    • Appleに相談
    • Apple Developer Center
    • App Store Awards(英語)
    • Apple Design Awards
    • Apple Developer Academy(英語)
    • WWDC
    最新ニュースを読む。
    Apple Developerアプリを入手する。
    Copyright © 2026 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン