<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Ios-Simulator on Tarragon</title><link>https://tarrragon.github.io/blog/tags/ios-simulator/</link><description>Recent content in Ios-Simulator on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Sun, 05 Jul 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/ios-simulator/index.xml" rel="self" type="application/rss+xml"/><item><title>iOS Simulator Runtime 架構：為什麼一組要 16G</title><link>https://tarrragon.github.io/blog/macos/macos_ios_simulator_runtime_architecture/</link><pubDate>Sun, 05 Jul 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/macos/macos_ios_simulator_runtime_architecture/</guid><description>&lt;p>iOS Simulator 讓開發者在 Mac 上跑 iOS App 而不需要實體裝置。每個 Simulator runtime 對應一個 iOS 版本——裝了 iOS 18.2 和 18.3.1 兩組 runtime，就能在兩個版本上測試。每組 runtime 約 16G，是 Mac 上最大的單一空間消耗者之一，但這個數字在日常開發中不容易察覺，直到磁碟空間不夠才會被發現。&lt;/p>
&lt;h2 id="一組-runtime-的組成">一組 Runtime 的組成&lt;/h2>
&lt;p>一組 runtime 的體積幾乎全部來自兩個 DMG（disk image）——Bundle 和 Runtime 各承擔不同的職責。&lt;/p>
&lt;p>&lt;strong>Bundle DMG&lt;/strong>（約 8G）：包含 Simulator 的 Cryptex 安全元件和啟動資料。儲存在 &lt;code>/Library/Developer/CoreSimulator/Cryptex/Images/bundle/&lt;/code> 下。&lt;/p>
&lt;p>&lt;strong>Runtime DMG&lt;/strong>（約 8G）：包含完整的 iOS 檔案系統——所有系統框架、內建 App、字型、語言資源。儲存在 &lt;code>/System/Library/AssetsV2/com_apple_MobileAsset_iOSSimulatorRuntime/&lt;/code> 下。&lt;/p>
&lt;p>兩個 DMG 合起來約 16G，是一組 runtime 的完整大小。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 查看已安裝的 runtime 和總大小&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">xcrun simctl runtime list&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>




&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">== Disk Images ==
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">-- iOS --
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">iOS 18.3.1 (22D8075) - 07012283-CA3D-4437-8A5F-89AE5346EEED (Ready)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">Total Disk Images: 1 (8.1G)&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>simctl runtime list&lt;/code> 報的 8.1G 是 Runtime DMG 的大小，沒有包含 Bundle DMG。完整佔用要兩者相加。&lt;/p>
&lt;h2 id="dmg-掛載成獨立-apfs-container">DMG 掛載成獨立 APFS Container&lt;/h2>
&lt;p>使用 Simulator 時，macOS 把這兩個 DMG 掛載成獨立的 APFS Container。&lt;code>diskutil list&lt;/code> 會看到它們以 &lt;code>(disk image)&lt;/code> 標示：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">/dev/disk4 (disk image): → iOS 18.3.1 Simulator Bundle 9.0 GB
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">/dev/disk6 (disk image): → iOS 18.3.1 Simulator 19.8 GB&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>這些 Container 的 Physical Store 是 DMG 檔案本身——實際的磁碟空間消耗在主 Container（disk3）的 Data 卷上。刪除 runtime 回收的空間會反映在 Data 卷的可用空間，而不是讓這些 disk image Container 消失（它們會自動卸載）。&lt;/p>
&lt;p>Container 顯示的大小（9.0G、19.8G）是 DMG 內部的邏輯容量，比 DMG 檔案的實際磁碟佔用（各約 8G）略大，因為檔案系統有自己的 metadata 開銷。判斷空間佔用時看 DMG 檔案的 &lt;code>du&lt;/code> 值，不看 Container 的 Size。&lt;/p>
&lt;h2 id="為什麼每組要-16g">為什麼每組要 16G&lt;/h2>
&lt;p>iOS Simulator 是完整的 iOS 使用者空間環境——App 在 Simulator 上跑時，呼叫的是真正的 iOS 系統框架（UIKit、Foundation、SwiftUI），這些框架需要完整打包在 runtime 裡。Simulator 跑的是 x86_64 或 arm64 原生碼（Apple Silicon Mac 上是 arm64），所以框架二進位跟實體裝置上的不同，必須另外編譯一套。&lt;/p>
&lt;p>16G 裡大約的分佈：&lt;/p>
&lt;ul>
&lt;li>系統框架和 dyld shared cache：佔最大宗，包含所有 iOS 框架的預連結版本&lt;/li>
&lt;li>內建 App（Safari、設定、照片等）：Simulator 需要完整的系統環境&lt;/li>
&lt;li>多語言資源：字型、語言包、輔助使用資源&lt;/li>
&lt;li>Cryptex 安全元件：跟 macOS 的 Cryptex 機制類似（見 &lt;a href="../macos_preboot_volume_check/">Preboot 卷&lt;/a>），讓 Simulator 的安全元件可以獨立更新&lt;/li>
&lt;/ul>
&lt;p>相鄰版本（如 18.2 和 18.3.1）共用大部分內容，但 Apple 目前不做跨版本 delta 壓縮——每組 runtime 是完整獨立的。這是為什麼裝兩組就是 32G、三組就是 48G，線性增長。&lt;/p></description><content:encoded><![CDATA[<p>iOS Simulator 讓開發者在 Mac 上跑 iOS App 而不需要實體裝置。每個 Simulator runtime 對應一個 iOS 版本——裝了 iOS 18.2 和 18.3.1 兩組 runtime，就能在兩個版本上測試。每組 runtime 約 16G，是 Mac 上最大的單一空間消耗者之一，但這個數字在日常開發中不容易察覺，直到磁碟空間不夠才會被發現。</p>
<h2 id="一組-runtime-的組成">一組 Runtime 的組成</h2>
<p>一組 runtime 的體積幾乎全部來自兩個 DMG（disk image）——Bundle 和 Runtime 各承擔不同的職責。</p>
<p><strong>Bundle DMG</strong>（約 8G）：包含 Simulator 的 Cryptex 安全元件和啟動資料。儲存在 <code>/Library/Developer/CoreSimulator/Cryptex/Images/bundle/</code> 下。</p>
<p><strong>Runtime DMG</strong>（約 8G）：包含完整的 iOS 檔案系統——所有系統框架、內建 App、字型、語言資源。儲存在 <code>/System/Library/AssetsV2/com_apple_MobileAsset_iOSSimulatorRuntime/</code> 下。</p>
<p>兩個 DMG 合起來約 16G，是一組 runtime 的完整大小。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 查看已安裝的 runtime 和總大小</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">xcrun simctl runtime list</span></span></code></pre></div>




<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">== Disk Images ==
</span></span><span class="line"><span class="ln">2</span><span class="cl">-- iOS --
</span></span><span class="line"><span class="ln">3</span><span class="cl">iOS 18.3.1 (22D8075) - 07012283-CA3D-4437-8A5F-89AE5346EEED (Ready)
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl">Total Disk Images: 1 (8.1G)</span></span></code></pre></div><p><code>simctl runtime list</code> 報的 8.1G 是 Runtime DMG 的大小，沒有包含 Bundle DMG。完整佔用要兩者相加。</p>
<h2 id="dmg-掛載成獨立-apfs-container">DMG 掛載成獨立 APFS Container</h2>
<p>使用 Simulator 時，macOS 把這兩個 DMG 掛載成獨立的 APFS Container。<code>diskutil list</code> 會看到它們以 <code>(disk image)</code> 標示：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">/dev/disk4 (disk image):    →  iOS 18.3.1 Simulator Bundle    9.0 GB
</span></span><span class="line"><span class="ln">2</span><span class="cl">/dev/disk6 (disk image):    →  iOS 18.3.1 Simulator           19.8 GB</span></span></code></pre></div><p>這些 Container 的 Physical Store 是 DMG 檔案本身——實際的磁碟空間消耗在主 Container（disk3）的 Data 卷上。刪除 runtime 回收的空間會反映在 Data 卷的可用空間，而不是讓這些 disk image Container 消失（它們會自動卸載）。</p>
<p>Container 顯示的大小（9.0G、19.8G）是 DMG 內部的邏輯容量，比 DMG 檔案的實際磁碟佔用（各約 8G）略大，因為檔案系統有自己的 metadata 開銷。判斷空間佔用時看 DMG 檔案的 <code>du</code> 值，不看 Container 的 Size。</p>
<h2 id="為什麼每組要-16g">為什麼每組要 16G</h2>
<p>iOS Simulator 是完整的 iOS 使用者空間環境——App 在 Simulator 上跑時，呼叫的是真正的 iOS 系統框架（UIKit、Foundation、SwiftUI），這些框架需要完整打包在 runtime 裡。Simulator 跑的是 x86_64 或 arm64 原生碼（Apple Silicon Mac 上是 arm64），所以框架二進位跟實體裝置上的不同，必須另外編譯一套。</p>
<p>16G 裡大約的分佈：</p>
<ul>
<li>系統框架和 dyld shared cache：佔最大宗，包含所有 iOS 框架的預連結版本</li>
<li>內建 App（Safari、設定、照片等）：Simulator 需要完整的系統環境</li>
<li>多語言資源：字型、語言包、輔助使用資源</li>
<li>Cryptex 安全元件：跟 macOS 的 Cryptex 機制類似（見 <a href="../macos_preboot_volume_check/">Preboot 卷</a>），讓 Simulator 的安全元件可以獨立更新</li>
</ul>
<p>相鄰版本（如 18.2 和 18.3.1）共用大部分內容，但 Apple 目前不做跨版本 delta 壓縮——每組 runtime 是完整獨立的。這是為什麼裝兩組就是 32G、三組就是 48G，線性增長。</p>
<h2 id="裝幾組合理">裝幾組合理</h2>
<p>判準是開發工作實際需要測試的 iOS 版本數量：</p>
<p><strong>一組（最新版）</strong>：適合多數開發者。Flutter 和 SwiftUI 開發通常只需要在最新 iOS 上測試，舊版相容性問題靠 API availability check 處理，不需要實際跑 Simulator。</p>
<p><strong>兩組（最新 + 上一個大版本）</strong>：App 的 deployment target 設在上一個大版本（例如 iOS 17）時，需要在該版本上跑 UI 測試確認佈局和行為。</p>
<p><strong>三組以上</strong>：企業 App 支援更舊的 iOS 版本，或需要測試跨版本升級行為。這種情況下空間成本是已知的取捨。</p>
<p>不確定時，先裝最新版，需要舊版時再下載——Xcode 會在建置或開啟 Simulator 時提示，下載約需 30 分鐘（視網路速度）。</p>
<h2 id="跟磁碟空間排查的關係">跟磁碟空間排查的關係</h2>
<p>Simulator runtime 的空間佔用有兩個特徵讓它在排查時容易被忽略：</p>
<ol>
<li>
<p><strong>DMG 檔案不在家目錄下</strong>：<code>du -shx ~/*</code> 不會掃到它們，因為 DMG 儲存在 <code>/System/Library/AssetsV2/</code> 和 <code>/Library/Developer/CoreSimulator/</code>。家目錄層的排查會完全漏掉這塊。</p>
</li>
<li>
<p><strong>掛載後的 Container 看起來像獨立磁碟</strong>：<code>diskutil apfs list</code> 列出的 Simulator Container 容易被誤認為是獨立的磁碟空間佔用，但它們的 Physical Store 是 Data 卷上的 DMG 檔案。理解 APFS 的 Container/Physical Store 關係（見 <a href="../macos_apfs_volume_structure/">APFS 卷結構</a>）後，這個混淆就消除了。</p>
</li>
</ol>
<p><a href="https://github.com/tarrragon/scripts">disk-report</a> 腳本的完整診斷模式會列出已安裝的 Simulator runtime，多版本時標記 redundant。移除多餘版本的操作流程見 <a href="../macos_remove_redundant_ios_simulators/">移除多餘 iOS Simulator</a>。</p>
]]></content:encoded></item><item><title>macOS 移除多餘的 iOS Simulator Runtime</title><link>https://tarrragon.github.io/blog/macos/macos_remove_redundant_ios_simulators/</link><pubDate>Sun, 05 Jul 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/macos/macos_remove_redundant_ios_simulators/</guid><description>&lt;p>每組 &lt;a href="../macos_ios_simulator_runtime_architecture/">iOS Simulator runtime&lt;/a> 約 16G（Bundle DMG + Runtime DMG），裝了兩個版本就佔 32G 以上。Flutter 和 Xcode 開發通常只需要最新版，舊版可以安全移除。移除的正確路徑是透過 Xcode 或 &lt;code>simctl&lt;/code> 指令，不是手動刪除 &lt;code>~/Library/Containers&lt;/code> 裡的檔案。&lt;/p>
&lt;h2 id="確認目前裝了幾組">確認目前裝了幾組&lt;/h2>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">xcrun simctl runtime list&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>輸出範例：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">== Disk Images ==
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">-- iOS --
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">iOS 18.2 (22C150) - 6286F286-FA4F-4877-AAEF-62A162C6A2C4 (Ready)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">iOS 18.3.1 (22D8075) - 07012283-CA3D-4437-8A5F-89AE5346EEED (Ready)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">Total Disk Images: 2 (16.2G)&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>兩組各自獨立，可以分開移除。&lt;/p>
&lt;h2 id="移除流程">移除流程&lt;/h2>
&lt;p>先清掉綁在舊 runtime 上的模擬器裝置，再刪 runtime 本體。順序顛倒的話，runtime 可能因為仍被裝置參照而拒絕刪除。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 1. 關閉所有正在跑的模擬器&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">xcrun simctl shutdown all
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">killall Simulator 2&amp;gt;/dev/null
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">&lt;span class="c1"># 2. 清掉不可用的模擬器裝置（綁在已刪 runtime 或舊版本上的）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">xcrun simctl delete unavailable
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">&lt;span class="c1"># 3. 刪除指定 runtime（用 runtime list 裡的 identifier）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">xcrun simctl runtime delete 6286F286-FA4F-4877-AAEF-62A162C6A2C4
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">&lt;span class="c1"># 4. 確認&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">xcrun simctl runtime list&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>如果步驟 3 跑完沒報錯但 runtime 還在列表裡，通常是因為還有模擬器裝置綁在上面。回到步驟 1 和 2 重跑，或用 &lt;code>xcrun simctl list devices&lt;/code> 查看哪些裝置還在用那個 runtime，手動刪掉它們：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 列出所有模擬器裝置&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">xcrun simctl list devices
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 刪除特定裝置&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">xcrun simctl delete &amp;lt;裝置UDID&amp;gt;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="為什麼不能手動刪檔案">為什麼不能手動刪檔案&lt;/h2>
&lt;p>一組 runtime 的資料散在多個位置（Runtime DMG、Bundle DMG、裝置資料、快取），各位置的關係和儲存機制見 &lt;a href="../macos_ios_simulator_runtime_architecture/">runtime 架構&lt;/a>。手動刪其中一處只會刪掉一部分，留下孤兒資料，讓 CoreSimulator 的索引跟實際檔案不一致。之後可能出現模擬器列表裡有裝置但開不了、或空間沒真正釋放的情況。&lt;code>simctl runtime delete&lt;/code> 會同步清理所有相關位置。&lt;/p>
&lt;h2 id="xcode-gui-的限制">Xcode GUI 的限制&lt;/h2>
&lt;p>Xcode &amp;gt; Settings &amp;gt; Platforms 也可以管理 runtime，但它把相鄰版本打包成同一個下載單位顯示。例如 iOS 18.2 和 18.3.1 在介面上可能顯示為一個 8.71GB 的「iOS 18.2 + iOS 18.3.1 Simulator」項目，無法單獨刪除其中一個。這時用 &lt;code>simctl&lt;/code> 指令是更精確的選擇。&lt;/p>
&lt;h2 id="刪完之後">刪完之後&lt;/h2>
&lt;p>重跑 &lt;a href="../macos_disk_space_diagnosis/">disk-report&lt;/a> 確認空間釋放。如果日後需要被刪除的版本，Xcode 會在建置或開啟模擬器時提示下載，或手動從 Settings &amp;gt; Platforms 下載。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 驗證空間釋放&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">df -h /System/Volumes/Data
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">xcrun simctl runtime list&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description><content:encoded><![CDATA[<p>每組 <a href="../macos_ios_simulator_runtime_architecture/">iOS Simulator runtime</a> 約 16G（Bundle DMG + Runtime DMG），裝了兩個版本就佔 32G 以上。Flutter 和 Xcode 開發通常只需要最新版，舊版可以安全移除。移除的正確路徑是透過 Xcode 或 <code>simctl</code> 指令，不是手動刪除 <code>~/Library/Containers</code> 裡的檔案。</p>
<h2 id="確認目前裝了幾組">確認目前裝了幾組</h2>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">xcrun simctl runtime list</span></span></code></pre></div><p>輸出範例：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">== Disk Images ==
</span></span><span class="line"><span class="ln">2</span><span class="cl">-- iOS --
</span></span><span class="line"><span class="ln">3</span><span class="cl">iOS 18.2 (22C150) - 6286F286-FA4F-4877-AAEF-62A162C6A2C4 (Ready)
</span></span><span class="line"><span class="ln">4</span><span class="cl">iOS 18.3.1 (22D8075) - 07012283-CA3D-4437-8A5F-89AE5346EEED (Ready)
</span></span><span class="line"><span class="ln">5</span><span class="cl">
</span></span><span class="line"><span class="ln">6</span><span class="cl">Total Disk Images: 2 (16.2G)</span></span></code></pre></div><p>兩組各自獨立，可以分開移除。</p>
<h2 id="移除流程">移除流程</h2>
<p>先清掉綁在舊 runtime 上的模擬器裝置，再刪 runtime 本體。順序顛倒的話，runtime 可能因為仍被裝置參照而拒絕刪除。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 1. 關閉所有正在跑的模擬器</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">xcrun simctl shutdown all
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">killall Simulator 2&gt;/dev/null
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"># 2. 清掉不可用的模擬器裝置（綁在已刪 runtime 或舊版本上的）</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">xcrun simctl delete unavailable
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1"># 3. 刪除指定 runtime（用 runtime list 裡的 identifier）</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">xcrun simctl runtime delete 6286F286-FA4F-4877-AAEF-62A162C6A2C4
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c1"># 4. 確認</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">xcrun simctl runtime list</span></span></code></pre></div><p>如果步驟 3 跑完沒報錯但 runtime 還在列表裡，通常是因為還有模擬器裝置綁在上面。回到步驟 1 和 2 重跑，或用 <code>xcrun simctl list devices</code> 查看哪些裝置還在用那個 runtime，手動刪掉它們：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 列出所有模擬器裝置</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">xcrun simctl list devices
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 刪除特定裝置</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">xcrun simctl delete &lt;裝置UDID&gt;</span></span></code></pre></div><h2 id="為什麼不能手動刪檔案">為什麼不能手動刪檔案</h2>
<p>一組 runtime 的資料散在多個位置（Runtime DMG、Bundle DMG、裝置資料、快取），各位置的關係和儲存機制見 <a href="../macos_ios_simulator_runtime_architecture/">runtime 架構</a>。手動刪其中一處只會刪掉一部分，留下孤兒資料，讓 CoreSimulator 的索引跟實際檔案不一致。之後可能出現模擬器列表裡有裝置但開不了、或空間沒真正釋放的情況。<code>simctl runtime delete</code> 會同步清理所有相關位置。</p>
<h2 id="xcode-gui-的限制">Xcode GUI 的限制</h2>
<p>Xcode &gt; Settings &gt; Platforms 也可以管理 runtime，但它把相鄰版本打包成同一個下載單位顯示。例如 iOS 18.2 和 18.3.1 在介面上可能顯示為一個 8.71GB 的「iOS 18.2 + iOS 18.3.1 Simulator」項目，無法單獨刪除其中一個。這時用 <code>simctl</code> 指令是更精確的選擇。</p>
<h2 id="刪完之後">刪完之後</h2>
<p>重跑 <a href="../macos_disk_space_diagnosis/">disk-report</a> 確認空間釋放。如果日後需要被刪除的版本，Xcode 會在建置或開啟模擬器時提示下載，或手動從 Settings &gt; Platforms 下載。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 驗證空間釋放</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">df -h /System/Volumes/Data
</span></span><span class="line"><span class="ln">3</span><span class="cl">xcrun simctl runtime list</span></span></code></pre></div>]]></content:encoded></item></channel></rss>