title: Creating a threadsafe Array, the easy way?
body: <p>I've just read <a href="http://basememara.com/creating-thread-safe-arrays-in-swift/" rel="nofollow noreferrer">a post by Basem Emara</a> about creating a threadsafe array Type in Swift. While I glanced through the code example, I asked myself if there isn't a way to achieve this with quite less code.</p>
  
  <p>Suppose I create this class:</p>
  
  <pre class="lang-swift prettyprint-override"><code>// MARK: Class Declaration
  class ThreadsafeArray&lt;Element&gt; {
      // Private Variables
      private var __array: [Element] = []
      private var __arrayQueue: DispatchQueue = DispatchQueue(
          label: "ThreadsafeArray.__concurrentArrayQueue",
          attributes: .concurrent
      )
  }
  
  
  // MARK: Interface
  extension ThreadSafeArray {
      // ReadWrite Variables
      var threadsafe: [Element] {
          get {
              return self.__arrayQueue.sync {
                  return self.__array
              }
          }
          set(newArray) {
              self.__arrayQueue.async(flags: .barrier) {
                  self.__array = newArray
              }
          }
      }
  }
  </code></pre>
  
  <p>If, from now on, I only accessed the actual array through <code>.threadsafe</code>, would this suffice to make the array threadsafe?</p>
  
  <p>Also, could I implement it a struct instead of a class to get the mutating checks as well?</p>
  
  <p>I am aware that the objects inside this array would not be threadsafe themselves through this but this is not the point, so let's assume I only put threadsafe stuff in there.</p>
  
  <p>(Of course, to avoid the calls to <code>.threadsafe</code>, I would make the shiny new class conform to <code>ExpressibleByArrayLiteral</code>, <code>Collection</code> and <code>RangeReplaceableCollection</code>, so I can use it like a normal array.</p>
  
  <hr>
  
  <h2>Edit</h2>
  
  <p>Meanwhile, I've tried testing it <a href="http://basememara.com/creating-thread-safe-arrays-in-swift/" rel="nofollow noreferrer">in a playground</a> and have come to believe that it doesn't suffice. </p>
  
  <h3>Playground code:</h3>
  
  <pre class="lang-swift prettyprint-override"><code>import Foundation
  import PlaygroundSupport
  
  
  PlaygroundPage.current.needsIndefiniteExecution = true
  
  // Testing //
  // Thread-unsafe array
  func unsafeArray() {
      var array: [Int] = []
      var iterations: Int = 1000
      let start: TimeInterval = Date().timeIntervalSince1970
  
      DispatchQueue.concurrentPerform(iterations: iterations) { index in
          let last: Int = array.last ?? 0
          array.append(last + 1)
  
          DispatchQueue.global().sync {
              iterations -= 1
  
              // Final loop
              guard iterations &lt;= 0 else { return }
              print(String(
                  format: "Unsafe loop took %.3f seconds, count: %d.",
                  Date().timeIntervalSince1970 - start, array.count
              ))
          }
      }
  }
  
  // Thread-safe array
  func safeArray() {
      let array: ThreadsafeArray&lt;Int&gt; = ThreadsafeArray&lt;Int&gt;()
      var iterations: Int = 1000
      let start: TimeInterval = Date().timeIntervalSince1970
  
      DispatchQueue.concurrentPerform(iterations: iterations) { index in
          let last: Int = array.threadsafe.last ?? 0
          array.threadsafe.append(last + 1)
  
          DispatchQueue.global().sync {
              iterations -= 1
  
              // Final loop
              guard iterations &lt;= 0 else { return }
              print(String(
                  format: "Safe loop took %.3f seconds, count: %d.",
                  Date().timeIntervalSince1970 - start, array.threadsafe.count
              ))
          }
      }
  }
  
  unsafeArray()
  safeArray()
  </code></pre>
  
  <h3>Output:</h3>
  
  <p>Most of the time:</p>
  
  <pre><code>experiments(31117,0x7000038d0000) malloc: *** error for object 0x11f663d28: pointer being freed was not allocated
  </code></pre>
  
  <p>*** set a breakpoint in malloc_error_break to debug</p>
  
  <p>Sometimes:</p>
  
  <pre><code>IndexError: Index out of range
  </code></pre>
  
  <p>Unfortunately also:</p>
  
  <pre><code>Unsafe loop took 1.916 seconds, count: 994.
  Safe loop took 11.258 seconds, count: 515.
  </code></pre>
  
  <p>Doesn't seem to suffice (also, it's incredibly unperformant).</p>