2014-11-25 180 views
8

我在移除我的代碼中的Firebase觀察者時遇到問題。下面是結構的崩潰:Firebase移除觀察者

var ref = Firebase(url:"https://MY-APP.firebaseio.com/") 
var handle = UInt? 

override func viewDidLoad() { 
    handle = ref.observeEventType(.ChildChanged, withBlock: { 
     snapshot in 

     //Do something with the data 
    } 
} 

override func viewWillDisappear(animated: Bool) { 
    if handle != nil { 
     println("Removed the handle") 
     ref.removeObserverWithHandle(handle!) 
    } 
} 

現在,當我離開的ViewController,我看到「刪除了手柄」被打印出來,但是當我返回到ViewController,我的觀察是對每個事件調用兩次。當我離開並再次返回時,它被稱爲三次。等等爲什麼觀察者不被移除?

我也在代碼後面打電話ref.setValue("some value"),這可能與它有什麼關係嗎?

+0

也有這個問題,只是發送了一個bug報告給firebase支持。由於它在2個月內不固定,可能不會很快修復 – Cymric 2015-02-13 00:39:54

+0

@Cymric嘿男人,對此有何更新?任何迴應 ?我真的需要一些解決方案。 – Bonnke 2015-07-03 14:52:17

+0

不幸的是沒有。我在4個月前向火力支持團隊提交了一個複製bug的示例程序,並且從那以後就沒有收到任何消息。我建議你嘗試下面的Daniel K的解決方法。 – Cymric 2015-07-03 15:04:18

回答

1

鑑於這是2015年4月和缺陷仍然是圍繞我提出了一個解決方法的問題:

  • 手柄保持的參考(讓我們在一本字典和啓動一個新的觀察員之前說相同的事件類型檢查觀察者是否已經在那裏

把手周圍有非常低的足跡(基於一些官方評論:)),所以它不會傷害那麼多。

+0

對不起,我的答覆很慢,我開始在其他項目上工作,所以花了我一些時間來嘗試一下你的建議。雖然不理想,但它確實提供了一種解決方法,所以謝謝:) – 2015-05-23 13:29:56

+0

如果您在塊中使用無主引用self,這是一個大問題。我是否需要編輯所有弱引用或檢查每個實例是否爲零? – 2015-12-01 15:16:24

2

以爲我有這個錯誤,但實際上我試圖刪除錯誤的引用觀察員。

原代碼:

let ref: FIRDatabaseReference = FIRDatabase.database().reference() 
var childAddedHandles: [String:FIRDatabaseHandle] = [:] 

func observeFeedbackForUser(userId: String) { 
    if childAddedHandles[userId] == nil { // Check if observer already exists 

     // NOTE: - Error is caused because I add .child(userId) to my reference and 
     //  do not when I call to remove the observer. 

     childAddedHandles[userId] = ref.child(userId).observeEventType(.ChildAdded) { 
      [weak self] (snapshot: FIRDataSnapshot) in 

      if let post = snapshot.value as? [String:AnyObject], 
       let likes = post["likes"] as? Int where likes > 0 {    

       self?.receivedFeedback(snapshot.key, forUserId: userId)   
      } 
     } 
    } 
} 

func stopObservingUser(userId: String) { 
    // THIS DOES NOT WORK 

    guard let cah = childAddedHandles.removeValueForKey(userId) else { 
     print("Not observing user") 
     return 
    } 

    // Error! I did not add .child(userId) to my reference 
    ref.removeObserverWithHandle(cah) 
} 

固定碼:

func stopObservingUser(userId: String) { 
    // THIS WORKS 

    guard let cah = childAddedHandles.removeValueForKey(userId) else { 
     print("Not observing user") 
     return 
    } 

    // Add .child(userId) here 
    ref.child(userId).removeObserverWithHandle(cah) 
} 
0

觀察員必須在它們被投入相同的參考路徑上被刪除。並且發出的次數相同,或者對每個路徑使用ref.removeAllObservers()。

這裏有一個竅門我用,以保持它的整潔:

var fbObserverRefs = [FIRDatabaseReference]() // keep track of where observers defined. 

......然後,把觀察員viewDidLoad中():

fbObserverRefs.append(ref.child("user/\(uid)")) 
fbObserverRefs.last!.observe(.value, with: { snap in 
    // do the work... 
}) 

......然後,在viewWillDisappear() ,請注意刪除任何已發佈的觀察者:

// Only true when popped from the Nav Controller stack, ignoring pushes of 
// controllers on top. 
if isBeingDismissed || isMovingFromParentViewController { 
    fbObserverRefs.forEach({ $0.removeAllObservers() }) 
}