2017-07-31 90 views
0

我有以下情況。根控制器是UITabViewController。有一個ProfileViewController,其中我讓一個觀察者,用戶開始成爲朋友(然後屏幕功能改變)。 ProfileViewController可以用5個標籤中的4個標籤打開,所以當前用戶可以在四個地方以同一用戶打開屏幕。在以前的版本中,當ProfileViewController在一個地方打開時,我刪除了deinit中的觀察者,並且僅刪除了ref.removeAllObservers(),現在當用戶案例是這樣的時候,我開始在viewDidDisappear中使用句柄和刪除觀察者。我想演示一下代碼,看看它是否可以改進,以及在這種情況下我是否做得正確。使用Swift中Firebase中的句柄移除觀察者

我調用這個函數在viewWillAppear中

fileprivate func firObserve(_ isObserve: Bool) { 
     guard let _user = user else { return } 
     FIRFriendsDatabaseManager.shared.observeSpecificUserFriendshipStart(observer: self, isObserve: isObserve, userID: _user.id, success: { [weak self] (friendModel) in 
     }) { (error) in 

     } 
    } 

這是FIRFriendsDatabaseManager

fileprivate var observeSpecificUserFriendshipStartDict = [AnyHashable : UInt]() 


func observeSpecificUserFriendshipStart(observer: Any, isObserve: Bool, userID: String, success: ((_ friendModel: FriendModel) -> Void)?, fail: ((_ error: Error) -> Void)?) { 
     let realmManager = RealmManager() 
     guard let currentUserID = realmManager.getCurrentUser()?.id else { return } 
     DispatchQueue.global(qos: .background).async { 
      let specificUserFriendRef = Database.database().reference().child(MainGateways.friends.description).child(currentUserID).child(SubGateways.userFriends.description).queryOrdered(byChild: "friendID").queryEqual(toValue: userID) 

      if !isObserve { 
       guard let observerHashable = observer as? AnyHashable else { return } 
       if let handle = self.observeSpecificUserFriendshipStartDict[observerHashable] { 
        self.observeSpecificUserFriendshipStartDict[observerHashable] = nil 
        specificUserFriendRef.removeObserver(withHandle: handle) 
        debugPrint("removed handle", handle) 
       } 
       return 
      } 

      var handle: UInt = 0 

      handle = specificUserFriendRef.observe(.childAdded, with: { (snapshot) in 
       if snapshot.value is NSNull { 
        return 
       } 
       guard let dict = snapshot.value as? [String : Any] else { return } 
       guard let friendModel = Mapper<FriendModel>().map(JSON: dict) else { return } 

       if friendModel.friendID == userID { 
        success?(friendModel) 
       } 
      }, withCancel: { (error) in 
       fail?(error) 
      }) 

      guard let observerHashable = observer as? AnyHashable else { return } 
      self.observeSpecificUserFriendshipStartDict[observerHashable] = handle 
     } 
    } 
+0

因此,從我的理解,你的代碼運行正常,你的問題只是:'有沒有比我做的更好的方式來做到這一點?如果這是正確的。這是我的反饋。考慮到你所描述的你想要完成的事情,你的邏輯對我來說似乎是合理的。作爲代碼「obserSpecificUserFriendshipStart」的一般反饋意見,可以重構爲更具可讀性。 – Doug

+0

@Doug是的,你正確理解了這個問題,我最不喜歡它,我在字典中存儲了控制器的鏈接,所以我想也許有更好的選擇) – Alexander

+0

@Doug在這個變體中,有一個很大的缺點例如,如果有任何情況可以刪除deinit中的觀察者,那麼管理器將獲得一個指向字典中控制器的鏈接。 – Alexander

回答

1

關於你保持每個的viewController一個參考實現,我會考慮的邏輯移動到的延伸viewController本身。

如果您想避免像以前一樣調用ref.removeAllObservers(),並且假設每個viewController只有一個這樣的偵聽器。我會讓偵聽器在視圖控制器上引用一個變量。

這樣一切都包含在viewController中。如果其他類型的viewController將對偵聽器進行類似的管理,它也可能是創建協議的一個很好的選擇。

相關問題