2016-04-15 8 views
0

Я пытаюсь загрузить данные окна сообщения для функций чата.leaky listener 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) 


} 

, так как я использую 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) 
} 

Есть несколько других слушателей, подобных этому. проблема заключается в том, когда я вернусь из этого представления (отдельный чат в поле сообщения, потребление памяти увеличивается.Я очистил все массивы и закрыл обработчики сразу после использования, но все равно потребление памяти увеличивается, а иногда в окне сообщения повторяются те же строки .. как я должен решить эту проблему, я попытался с помощью observeSingleEventOfType, но это не является правильным решением, поскольку синхронизация данных прекращается

Используется это в качестве справки:. https://www.firebase.com/blog/2015-10-15-best-practices-uiviewcontroller-ios-firebase.html

ответ

0

Проблема заключалась в том, что я закрывал слушателей на родителей, а не на ребенка. поэтому слушатели все еще были в памяти. Когда я закрыл слушателей на полном пути, он сработал.

1

похоже вашего сообщения объекта коробки не являющегося выпущенный из-за цикла сохранения, вызванного блоком обратного вызова слушателя, содержащим ссылку на объект окна сообщения. Вы можете облегчить это, используя [слабое я] в блоках, которые вы передаете o все объекты. Например:

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

        let enumerator = roomsnapshot.children 
        ... 

Это делает «я» дополнительный тип, а затем вы можете добавить:

guard let strongSelf = self else { ... }