我正在尝试加载聊天功能的消息框数据。
消息框加载为:
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 :(得分:2)
由于侦听器回调块保持对消息框对象的引用而导致保留周期,因此看起来您的消息框对象未被释放。您可以通过在传递给其他对象的块中使用[weak self]来缓解此问题。例如:
.observeSingleEventOfType(.Value, withBlock:
{
[weak self] roomsnapshot in
let enumerator = roomsnapshot.children
...
这使'self'成为可选类型,然后您可以添加:
guard let strongSelf = self else { ... }
答案 1 :(得分:0)
问题是我关闭了父母的听众,而不关闭孩子。所以听众仍然记忆犹新。 当我在完整路径上关闭听众时,它就起作用了。