2016-04-15 9 views
0

チャット機能のメッセージボックスのデータを読み込もうとしています。リーキーリスナーfirebase ios

override func viewDidAppear(animated: Bool) { 
      super.viewDidAppear(animated) 

if (PFUser.currentUser()!["firebaseUID"] !== nil) 
{ 
    print(PFUser.currentUser()!["firebaseUID"]) 
    self.updateResultArray(PFUser.currentUser()!["firebaseUID"] as! String) 
} 
} 

    func updateResultArray(uid: String) { 


    let userName = String(PFUser.currentUser()!["username"]) 

    //print("updateResultArray is getting called") 
    let userhandle = self.firebase.childByAppendingPath("users").childByAppendingPath(uid).childByAppendingPath("rooms").queryOrderedByValue() 
     .observeSingleEventOfType(.Value, withBlock: { roomsnapshot in 

      let enumerator = roomsnapshot.children 
      while let rest = enumerator.nextObject() as? FDataSnapshot { 
       self.roomArray.append(rest.key) 
      } 

      //get the latest message from all the rooms 
      if self.roomArray.isEmpty == false 
      { 
       for i in 0...self.roomArray.count-1 
       { 
        print("in the room loop \(self.roomArray[i])") 

        let messagehandle = self.messagesRef.childByAppendingPath(self.roomArray[i]).queryOrderedByKey().queryLimitedToFirst(1).observeSingleEventOfType(.Value, withBlock: { 
         messagesnapshot in 

         print("the messagesnapshot child count is \(messagesnapshot.childrenCount)") 
         let enumerator = messagesnapshot.children 
         while let rest = enumerator.nextObject() as? FDataSnapshot { 

          let sender = rest.value.objectForKey("sender") as? String 
          let reciever = rest.value.objectForKey("reciever") as? String 

          //print("sender is \(sender!) and reciever is \(reciever!)") 


          let eventhandle = self.firebase.childByAppendingPath("rooms").childByAppendingPath(self.roomArray[i]).observeSingleEventOfType(.Value, withBlock: { eventsnapshot in 

           if eventsnapshot.value is NSNull { 
            // The value is null 
           } 
           else 
           { 
           let eventAttr = eventsnapshot.value.objectForKey("eventAttributes") as? String 
           let eventDetails = eventsnapshot.value.objectForKey("eventDetails") as? String 


           //print("userName is \(userName)") 
           //print("sender is \(sender)") 
           if (userName != sender!) //for event joinee 
           { 
            let firstname1 = eventsnapshot.value.objectForKey("firstname1") as? String 
            self.otherNames.append(sender!) 
            self.resultsNameArray.append(firstname1!) 
            self.base4String = eventsnapshot.value.objectForKey("img1") as! String 
            self.resultsImageFiles.append(self.base4String) 

           } 
           else //for event creator 
           { 
            let firstname2 = eventsnapshot.value.objectForKey("firstname2") as? String 
            self.otherNames.append(reciever!) 
            self.resultsNameArray.append(firstname2!) 
            self.base4String = eventsnapshot.value.objectForKey("img2") as! String 
            self.resultsImageFiles.append(self.base4String) 

           } 

           let newlineChars = NSCharacterSet.newlineCharacterSet() 
           let evntArray = eventDetails!.componentsSeparatedByCharactersInSet(newlineChars).filter{!$0.isEmpty} 
           self.eventArray.append(evntArray[0]) 

           self.eventdetailsArray.append(eventAttr!) 

           dispatch_async(dispatch_get_main_queue()) {() -> Void in 
            self.resultsTable.reloadData() 
           } 

           } 

          }) 

          // self.firebase.removeAuthEventObserverWithHandle(eventhandle) 
         } 

        }) 

        //self.messagesRef.removeAuthEventObserverWithHandle(messagehandle) 
       } 

      } 
     }) 


     //firebase.removeAuthEventObserverWithHandle(userhandle) 


} 

私はハンドラを削除するために符号化されたhaventはobserveSingleEventOfTypeを使用していますので、(私も同様ことを試みた)として

メッセージボックス

がロードされます。個人チャットで

、コードは次のようである:

func refreshResults() { 

    print("the roomid is \(roomid)") 

    //update from firebase 
    let messagehandle = self.messagesRef.childByAppendingPath(roomid).queryOrderedByKey() 
     .observeEventType(.Value, withBlock: { messageTextsnapshot in 

      self.messageArray.removeAll() 
      self.senderArray.removeAll() 


      //    print("the messageTextsnapshot child count is \(messageTextsnapshot.childrenCount)") // I got the expected number of items 
      let enumerator = messageTextsnapshot.children 
      while let rest = enumerator.nextObject() as? FDataSnapshot { 


       let text = rest.value.objectForKey("message") as? String 
       let sender = rest.value.objectForKey("sender") as? String 


       if text != nil && text != "" 
       { 

        self.messageArray.append(text!) 
        self.senderArray.append(sender!) 

       } 

      } 


      for subView in self.resultsScrollView.subviews { 
       subView.removeFromSuperview() 
      } 

      for var i = 0; i <= self.messageArray.count-1; i++ { 


       if self.senderArray[i] == userName { 


        if (self.messageArray[i].rangeOfString(self.acceptMessage) != nil) 
        { 

         let chatBubbleData = ChatBubbleData(text: self.messageArray[i], image:self.myImg, date: NSDate(), type: .AcceptMine) 

         self.addChatBubble(chatBubbleData) 

        } 
        else 
        { 

         let chatBubbleData = ChatBubbleData(text: self.messageArray[i], image:self.myImg, date: NSDate(), type: .Mine) 

         self.addChatBubble(chatBubbleData) 

        } 

       } else { 

        if (self.messageArray[i].rangeOfString(self.acceptMessage) != nil) 
        { 

         let chatBubbleData = ChatBubbleData(text: self.messageArray[i], image:self.otherImg, date: NSDate(), type: .Accept) 

         self.addChatBubble(chatBubbleData) 

        } 
        else 
        { 

         let chatBubbleData = ChatBubbleData(text: self.messageArray[i], image:self.otherImg, date: NSDate(), type: .Opponent) 

         self.addChatBubble(chatBubbleData) 
        } 
       } 

       let bottomOffset:CGPoint = CGPointMake(0, self.resultsScrollView.contentSize.height - self.resultsScrollView.bounds.size.height) 
       self.resultsScrollView.setContentOffset(bottomOffset, animated: false) 

      } 


     }) 

    self.messagesRef.removeAuthEventObserverWithHandle(messagehandle) 
} 

これに似たいくつかの他のリスナーがあります。問題は、私はこのビュー(個々のチャットをメッセージボックスに戻って、メモリ消費量が増加する。私はすべての配列をクリアし、使用後すぐにハンドラを閉じたが、メモリ消費量が増加し、時にはメッセージボックスの同じ行が。あなたのメッセージボックスオブジェクトがされていないように見えます https://www.firebase.com/blog/2015-10-15-best-practices-uiviewcontroller-ios-firebase.html

答えて

0

問題は、私は子供に親のリスナーを閉じていなかったということでした。リスナーはまだ記憶に残っていました。 フルパスでリスナーを閉じたとき、それはうまくいった。

1

:どのように私はこの問題を解決する必要があり、私は observeSingleEventOfTypeを使用してみましたが、データの同期が停止すると、それが正しい解決策ではありません

参照としてこれを使用します。メッセージボックスオブジェクトへの参照を保持するリスナコールバックブロックによって保持サイクルが発生したために解放されました。これを軽減するには、oに渡すブロックで[weak self]を使用しますオブジェクト。たとえば:

  .observeSingleEventOfType(.Value, withBlock: 
       { 
        [weak self] roomsnapshot in 

        let enumerator = roomsnapshot.children 
        ... 

これは「自己」オプションのタイプを行い、あなたがして追加することができます。

guard let strongSelf = self else { ... } 
関連する問題