<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thai Dao</title>
    <description>The latest articles on DEV Community by Thai Dao (@thaidao6314).</description>
    <link>https://dev.to/thaidao6314</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3984038%2F8fbc9f58-4d12-4973-8b2c-f8084f1d6471.jpeg</url>
      <title>DEV Community: Thai Dao</title>
      <link>https://dev.to/thaidao6314</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thaidao6314"/>
    <language>en</language>
    <item>
      <title>Value Semantics vs Reference Semantics in Swift: A Practical Guide</title>
      <dc:creator>Thai Dao</dc:creator>
      <pubDate>Thu, 13 Aug 2026 16:09:21 +0000</pubDate>
      <link>https://dev.to/thaidao6314/value-semantics-vs-reference-semantics-in-swift-a-practical-guide-32k8</link>
      <guid>https://dev.to/thaidao6314/value-semantics-vs-reference-semantics-in-swift-a-practical-guide-32k8</guid>
      <description>&lt;h4&gt;
  
  
  When learning Swift, we often hear:
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;struct is a Value Type, while class is a Reference Type&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That statement is correct, but it doesn't explain what actually happens when we copy, mutate, or share data.&lt;/p&gt;

&lt;p&gt;In real-world iOS development, understanding Value Semantics, Reference Semantics, Copy-on-Write (CoW), and storage is much more useful than simply remembering "struct = stack, class = heap".&lt;/p&gt;

&lt;p&gt;Let's break it down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Value Semantics&lt;/strong&gt;&lt;br&gt;
A type has &lt;strong&gt;Value Semantics&lt;/strong&gt; when copying it creates an independent value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;

&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 10&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Changing b doesn't affect a.&lt;/p&gt;

&lt;p&gt;The same applies to a struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;user1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;user2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user1&lt;/span&gt;

&lt;span class="n"&gt;user2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Alice&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Bob&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conceptually:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user1 → User("Alice")
user2 → User("Bob")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important idea is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A copy behaves as an independent value.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;2. Reference Semantics&lt;/strong&gt;&lt;br&gt;
A class has &lt;strong&gt;Reference Semantics&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;

    &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;user1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;user2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user1&lt;/span&gt;

&lt;span class="n"&gt;user2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;

&lt;span class="o"&gt;-------------------&lt;/span&gt;
&lt;span class="kt"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Bob&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Bob&lt;/span&gt;

&lt;span class="o"&gt;-------------------&lt;/span&gt;
&lt;span class="kt"&gt;Why&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
&lt;span class="kt"&gt;Because&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="nv"&gt;user1&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="nv"&gt;user2&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="n"&gt;reference&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;same&lt;/span&gt; &lt;span class="nv"&gt;object&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;user1&lt;/span&gt; &lt;span class="err"&gt;─────┐&lt;/span&gt;
           &lt;span class="err"&gt;▼&lt;/span&gt;
       &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="kt"&gt;Object&lt;/span&gt;
       &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;
           &lt;span class="err"&gt;▲&lt;/span&gt;
           &lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="n"&gt;user2&lt;/span&gt; &lt;span class="err"&gt;─────┘&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Copying a reference type copies the reference, not the object.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is useful when we actually want shared identity and shared state—for example, a ViewModel, service, coordinator, or resource owner.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Don't Think struct = Stack and class = Heap&lt;/strong&gt;&lt;br&gt;
A common explanation is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct → Stack
class  → Heap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is too simplistic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack and Heap describe storage implementation, while Value and Reference Semantics describe behavior.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;Point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A small, fixed-size value like this can be stored inline. If it's a local variable, that representation may be on the stack, but the compiler is free to optimize it differently.&lt;/p&gt;

&lt;p&gt;On the other hand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;RingtoneStore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;ringtones&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Ringtone&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Array&lt;/code&gt; can contain 100,000 elements, so its data requires dynamic storage.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RingtoneStore
┌─────────────────────┐
│ Array representation│
└──────────┬──────────┘
           │
           ▼
     Backing Storage
     [Ringtone ...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Array&lt;/code&gt; value is still a &lt;strong&gt;Value Type&lt;/strong&gt;, even though its backing storage is dynamically allocated and commonly lives on the heap.&lt;/p&gt;

&lt;p&gt;So the better question is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Is this struct on the Stack or Heap?"&lt;br&gt;
but:&lt;br&gt;
"How is this value represented and where is its backing storage?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;4. Copy-on-Write&lt;/strong&gt;&lt;br&gt;
This becomes especially interesting with large collections.&lt;/p&gt;

&lt;p&gt;Suppose we have 100,000 ringtones:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;ringtones&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Ringtone&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ringtones&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Does Swift immediately copy all 100,000 elements?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Array&lt;/code&gt; uses &lt;strong&gt;Copy-on-Write (CoW)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a ─────┐
       ├──&amp;gt; Shared Storage
b ─────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are two Array values, but they can temporarily share the same backing storage.&lt;/p&gt;

&lt;p&gt;If we only read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;there is no reason to copy the storage.&lt;/p&gt;

&lt;p&gt;This makes copying a large Array relatively cheap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. What Happens When We Mutate?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;

&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before mutation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a ─────┐
       ├──&amp;gt; Storage A
b ─────┘
       [1, 2, 3]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;b&lt;/code&gt; modified Storage A directly, &lt;code&gt;a&lt;/code&gt; would also change. That would violate Value Semantics.&lt;/p&gt;

&lt;p&gt;So Swift separates the storage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a ─────────&amp;gt; Storage A
             [1, 2, 3]

b ─────────&amp;gt; Storage B
             [1, 2, 3, 4]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is Copy-on-Write.&lt;/p&gt;

&lt;p&gt;The important optimization is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Don't copy until mutation actually requires it.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;6. What Does "Uniquely Referenced" Mean?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CoW doesn't mean every mutation requires an &lt;code&gt;O(n)&lt;/code&gt; copy.&lt;/p&gt;

&lt;p&gt;Consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a is the only value using its backing storage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a ─────&amp;gt; Storage A
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the storage is &lt;strong&gt;uniquely referenced&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Swift can mutate it directly.&lt;/p&gt;

&lt;p&gt;But:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;gives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a ─────┐
       ├──&amp;gt; Storage A
b ─────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The storage is shared.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;b&lt;/code&gt; mutates, CoW may need to create a new storage.&lt;/p&gt;

&lt;p&gt;So the simplified model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mutation
   ↓
Is storage shared?
   │
   ├── No  → mutate in place
   │
   └── Yes → copy → mutate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the key to understanding the performance of Swift collections.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. A Struct Can Still Contain a Class&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's an important edge case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;AudioPlayer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;volume&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;Ringtone&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;player&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;AudioPlayer&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although &lt;code&gt;Ringtone&lt;/code&gt; is a struct, &lt;code&gt;player&lt;/code&gt; is a reference to a class instance.&lt;/p&gt;

&lt;p&gt;After:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let ringtone2 = ringtone1

we can have:

ringtone1 ──┐
            │
            ▼
       AudioPlayer
       volume = 50
            ▲
            │
ringtone2 ──┘

Therefore:

ringtone2.player.volume = 100

can also be observed through:

ringtone1.player.volume

because both structs share the same `AudioPlayer`.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives us an important rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A struct provides Value Semantics at its own level, but it does not automatically make every property deeply independent.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is why exposing mutable reference-type state directly from a value type should be done carefully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Value Semantics and Concurrency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Value Semantics are also useful in concurrent code because they reduce shared mutable state.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;UserState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If two tasks work with independent copies:&lt;/p&gt;

&lt;p&gt;Task A → UserState A&lt;br&gt;
Task B → UserState B&lt;/p&gt;

&lt;p&gt;then mutation in Task A doesn't change Task B's value.&lt;/p&gt;

&lt;p&gt;This significantly reduces opportunities for Data Races.&lt;/p&gt;

&lt;p&gt;However, it's important to be precise:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;struct&lt;/code&gt; &lt;strong&gt;does not automatically mean thread-safe.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A struct can still contain a mutable class reference or access external shared state.&lt;/p&gt;

&lt;p&gt;So a better statement is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Value Semantics reduce shared mutable state, which makes concurrent code easier to reason about and reduces potential data races.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The most useful mental model is not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct = Stack
class  = Heap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Value Type
    ↓
Value Semantics
    ↓
Independent state
    ↓
CoW can optimize storage sharing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reference Type
    ↓
Reference Semantics
    ↓
Shared identity
    ↓
Shared mutable state
    ↓
ARC manages lifetime
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when performance is involved:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Array copy
    ↓
Share backing storage
    ↓
Read → no copy
    ↓
Mutation
    ↓
Is storage unique?
   ├── Yes → mutate in place
   └── No  → Copy-on-Write
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you understand these relationships, concepts like &lt;strong&gt;Swift Concurrency&lt;/strong&gt;, &lt;code&gt;Sendable&lt;/code&gt;, &lt;strong&gt;ARC&lt;/strong&gt;, &lt;strong&gt;data races&lt;/strong&gt;, &lt;strong&gt;and collection performance&lt;/strong&gt; become much easier to reason about.&lt;/p&gt;

&lt;p&gt;The key takeaway is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Value vs Reference Semantics describe how data behaves. Stack vs Heap describes how data may be stored. Don't confuse the two.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>swift</category>
      <category>ios</category>
    </item>
    <item>
      <title>Stop Blocking Your Threads: Thread.sleep() vs. Task.sleep() in Swift</title>
      <dc:creator>Thai Dao</dc:creator>
      <pubDate>Sun, 14 Jun 2026 15:06:53 +0000</pubDate>
      <link>https://dev.to/thaidao6314/stop-blocking-your-threads-threadsleep-vs-tasksleep-in-swift-oh6</link>
      <guid>https://dev.to/thaidao6314/stop-blocking-your-threads-threadsleep-vs-tasksleep-in-swift-oh6</guid>
      <description>&lt;p&gt;When I first started exploring &lt;strong&gt;Swift Concurrency&lt;/strong&gt;, a simple question popped into&lt;br&gt;
my mind: "&lt;em&gt;We’ve had &lt;code&gt;Thread.sleep()&lt;/code&gt; for years and it works fine. Why did Apple introduce &lt;code&gt;Task.sleep()&lt;/code&gt;? Aren't they doing the exact same thing?&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;Well, after a few "frozen UI" incidents and some deep dives into the docs, I realized that while they both "pause" execution, their impact on the system is worlds apart.&lt;/p&gt;

&lt;p&gt;Let’s break it down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Thread.sleep(): The "Selfish" Way&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Thread.sleep(forTimeInterval:)&lt;/code&gt; is a synchronous operation. When you call this, you are telling the Operating System: "&lt;em&gt;Stop this entire thread right now. Don't let it do anything else for the next X seconds.&lt;/em&gt;"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This blocks the entire thread&lt;/span&gt;
&lt;span class="kt"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;forTimeInterval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I'm awake!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blocking&lt;/strong&gt;: If you call this on the &lt;strong&gt;Main Thread&lt;/strong&gt;, your UI freezes. No scrolling, no button clicks—nothing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Heavy&lt;/strong&gt;: The OS still has to maintain that thread's resources, even though it's sitting idle doing zero work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inefficient&lt;/strong&gt;: In a world of limited threads, "holding" a thread hostage while it sleeps is a waste of power.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Task.sleep(): The "Polite" Way&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Task.sleep()&lt;/code&gt; is built for the modern &lt;code&gt;async/await&lt;/code&gt; world. It doesn't block the thread; it &lt;strong&gt;suspends&lt;/strong&gt; the task.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This suspends the task, not the thread&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="kt"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Task resumed!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it’s better:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Non-blocking&lt;/strong&gt;: When a task hits &lt;code&gt;await Task.sleep()&lt;/code&gt;, it gives up its seat on the thread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread Reusability&lt;/strong&gt;: The Swift Concurrency runtime is smart. While your task is "sleeping," it uses that same thread to run other tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;System-Friendly&lt;/strong&gt;: Once the timer is up, the system finds an available thread to resume your task.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Analogy&lt;/strong&gt;: &lt;code&gt;Thread.sleep&lt;/code&gt; is like a person standing in the middle of a doorway to take a nap. No one can pass. &lt;code&gt;Task.sleep&lt;/code&gt; is like a person stepping out of the room to nap so others can still use the door.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;A Quick Note on "Blocking" and Deadlocks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Understanding the difference between &lt;strong&gt;blocking&lt;/strong&gt; and &lt;strong&gt;suspending&lt;/strong&gt; is key to avoiding the dreaded Deadlock.&lt;/p&gt;

&lt;p&gt;A classic mistake many of us have made is calling &lt;code&gt;.sync&lt;/code&gt; on the Main Thread from the Main Thread:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// DO NOT DO THIS on the Main Thread&lt;/span&gt;
&lt;span class="kt"&gt;DispatchQueue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sync&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This will never print"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why does this crash/hang?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Main Thread says&lt;/strong&gt;: "&lt;em&gt;I will wait until this block of code finishes before I move to the next line.&lt;/em&gt;" (That's what .&lt;code&gt;sync&lt;/code&gt; does).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The Block of Code&lt;/strong&gt; is sent to the Main Queue, waiting for the Main Thread to become free so it can run.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The Result&lt;/strong&gt;: The Thread is waiting for the Block, and the Block is waiting for the Thread. They are stuck in a "forever-waiting" loop. &lt;strong&gt;Deadlock&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The Verdict&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Thread.sleep() = Blocking&lt;/strong&gt;. Old school. Use only if you have a very specific reason to stop a background thread entirely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task.sleep() = Suspending&lt;/strong&gt;. Modern. Use this in 99% of your &lt;code&gt;async/await&lt;/code&gt; code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Rule of thumb&lt;/strong&gt;: In Swift Concurrency, think in &lt;strong&gt;Tasks&lt;/strong&gt;, not Threads. Don't block the pool; let the runtime manage the resources for you.&lt;/p&gt;

&lt;p&gt;Are you still using &lt;code&gt;Thread.sleep()&lt;/code&gt; in your projects, or have you fully migrated to &lt;code&gt;async/await&lt;/code&gt;? Let’s chat in the comments!&lt;/p&gt;

</description>
      <category>ios</category>
      <category>swift</category>
      <category>watercooler</category>
    </item>
  </channel>
</rss>
