title: iOS App crashed com.apple.root.background-qos
body: <p>An app crash was found in the application. I suspect that this could happen because of the code for firebase observers. Since in a user case, a user can go from one event to a user profile (which participates in this event) then from the user profile can go back to this event I needed a handle for ref to delete a specific observer. Because of this, I made the following code. </p>
  
  <p>Snippet of code </p>
  
  <pre><code>fileprivate func firObserve(_ isObserve: Bool) {
      guard card != nil else { return }
      firCardObserverDBManager.observeParticipationCard(observer: self, card: card, isObserve: isObserve, success: { [weak self] (updatedCard) in
              debugPrint("updated card")
              self?.checkUpdatedCard(updatedCard)
          }, removed: { [weak self] in
              self?.isParticipationCardDateRemoved = true
              self?.presentCardRemovedAlert()
      }) { (error) in
          DispatchQueue.main.async {
              SVProgressHUD.showError(withStatus: error.localizedDescription)
          }
      }
  }
  </code></pre>
  
  <p>from FIRCardObserverDBManager</p>
  
  <pre><code>    fileprivate var observeParticipationCardObservers = NSMapTable&lt;AnyObject, AnyObject&gt;(keyOptions: .weakMemory, valueOptions: .strongMemory)
  
  
  func observeParticipationCard(observer: Any, card: CardModel, isObserve: Bool, success: ((_ updatedCard: CardModel) -&gt; Void)?, removed: (() -&gt; Void)?, fail: ((_ error: Error) -&gt; Void)?) {
      let ref = Database.database().reference().child(MainGateways.cards.rawValue).child(card.id)
  
      if !isObserve {
          guard let handle = self.observeParticipationCardObservers.object(forKey: observer as AnyObject) as? UInt else { return }
          ref.removeObserver(withHandle: handle)
          observeParticipationCardObservers.removeObject(forKey: observer as AnyObject)
          return
      }
  
      if let observableVC = observer as? UIViewController {
          observableVC.firReferences.append(ref)
      }
  
      DispatchQueue.global(qos: .background).async {
          let handle = ref.observe(.value, with: { (snapshot) in
              if snapshot.value is NSNull {
                  // not exist
                  removed?()
              }
              guard let json = snapshot.value as? [String : Any] else { return }
              guard let updatedCard = Mapper&lt;CardModel&gt;().map(JSON: json) else { return }
              success?(updatedCard)
          }, withCancel: { (error) in
              debugPrint(error.localizedDescription)
              fail?(error)
          })
          self.observeParticipationCardObservers.setObject(handle as AnyObject, forKey: observer as AnyObject)
          debugPrint("observeParticipationCardObservers", self.observeParticipationCardObservers)
      }
  }
  </code></pre>
  
  <p>an UIViewController's extension for it </p>
  
  <pre><code>extension UIViewController {
  
      private struct FirebaseQueues {
          static var firQueues = [DatabaseQuery]()
      }
  
      var firQueues: [DatabaseQuery] {
          get {
              guard let firQueues = objc_getAssociatedObject(self, &amp;FirebaseQueues.firQueues) as? [DatabaseQuery] else { return [] }
              return firQueues
          }
          set {
              objc_setAssociatedObject(self, &amp;FirebaseQueues.firQueues, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
          }
      }
  
      private struct FirebaseReferences {
          static var firReferences = [DatabaseReference]()
      }
  
      var firReferences: [DatabaseReference] {
          get {
              guard let firReferenses = objc_getAssociatedObject(self, &amp;FirebaseReferences.firReferences) as? [DatabaseReference] else { return [] }
              return firReferenses
          }
          set {
              objc_setAssociatedObject(self, &amp;FirebaseReferences.firReferences, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
          }
      }
  
      func removeFIRQueuesReferensesObservers() {
          for firQueqry in firQueues {
              firQueqry.removeAllObservers()
          }
          firQueues.removeAll()
          for firRef in firReferences {
              firRef.removeAllObservers()
          }
          firReferences.removeAll()
      }
  
  }
  </code></pre>
  
  <p>Crash stack </p>
  
  <pre><code>   Crashed: com.apple.root.background-qos
      0  libswiftCore.dylib             0x1022ba574 swift_unknownRelease (__hidden#21375_:381)
      1  myapp                       0x1002e3fd0 specialized specialized _ArrayBufferProtocol._arrayOutOfPlaceUpdate&lt;A where ...&gt; (inout _ContiguousArrayBuffer&lt;A.Element&gt;, Int, Int, A1) -&gt; () (EventsUpcomingVC.swift)
      2  myapp                       0x1002e0eb8 specialized Array._copyToNewBuffer(oldCount : Int) -&gt; () (EventsUpcomingVC.swift)
      3  myapp                       0x100319a84 specialized ChatGeneralManager.(observeConversationModel(Bool, conversationID : String, updated : () -&gt; ()?, fail : (Error) -&gt; ()?) -&gt; ()).(closure #1).(closure #1) (ChatGeneralManager.swift)
      4  myapp                       0x100311f70 ChatGeneralManager.(observeConversationModel(Bool, conversationID : String, updated : () -&gt; ()?, fail : (Error) -&gt; ()?) -&gt; ()).(closure #1).(closure #1) (ChatGeneralManager.swift)
      5  myapp                       0x10032515c partial apply for ChatGeneralManager.(observeConversationModel(Bool, conversationID : String, updated : () -&gt; ()?, fail : (Error) -&gt; ()?) -&gt; ()).(closure #1).(closure #1) (ChatGeneralManager.swift)
      6  libdispatch.dylib              0x185b9e9e0 _dispatch_call_block_and_release + 24
      7  libdispatch.dylib              0x185b9e9a0 _dispatch_client_callout + 16
      8  libdispatch.dylib              0x185baebac _dispatch_root_queue_drain + 888
      9  libdispatch.dylib              0x185bae7d0 _dispatch_worker_thread3 + 124
      10 libsystem_pthread.dylib        0x185da7100 _pthread_wqthread + 1096
      11 libsystem_pthread.dylib        0x185da6cac start_wqthread + 4
  </code></pre>