运行覆盖FriendlyChat的Codelabs Firebase教程。解决了常见问题(在其他地方回答),但当我上传所选图像时,我的应用程序崩溃了。我重新编写了所有步骤并测试了教程源代码的“完整”版本,以确保它不是我正在做的事情。没运气。其他人都看到了这个问题吗?
以下是例外......
2016-05-23 17:25:13.119 FriendlyChatSwift [61549:15581893] ***由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无效更新:第0部分中的行数无效。行数更新后的现有部分中包含的(1)必须等于更新前该部分中包含的行数(6),加上或减去从该部分插入或删除的行数(插入1个,删除0个)加上或减去移入或移出该部分的行数(0移入,0移出)。'
当我在初始加载时检查消息计数时,它很好。当我转到imagePicker并返回时,突然消息计数为1,但行数仍为6。
问题似乎在这里:
override func viewWillAppear(animated: Bool) {
self.messages.removeAll()
// Listen for new messages in the Firebase database
_refHandle = self.ref.child("messages").observeEventType(.ChildAdded, withBlock: { (snapshot) -> Void in
self.messages.append(snapshot)
self.clientTable.insertRowsAtIndexPaths([NSIndexPath(forRow: self.messages.count-1, inSection: 0)], withRowAnimation: .Automatic)
})
}
如果删除所有消息,则在调用insertRowsAtIndexPaths时索引处于关闭状态。
答案 0 :(得分:2)
我通过将所有代码从viewWillAppear移动到viewDidLoad的末尾来实现此功能。因为每次视图再次显示时都会调用viewWillAppear,所以在您离开照片视图并返回到表视图后,它最终会被调用。另一方面,viewDidLoad仅在加载视图时调用一次。当用户返回主屏幕并返回应用程序时,它也可以工作。
找出真正的解决方案。关于这个twitter thread的讨论解释了你必须做什么以及为什么。 firebase提供的代码应该像viewDidAppear一样进入。但是,您需要在删除所有消息后重新加载表。
self.messages.removeAll()
self.clientTable.reloadData()
然后你的viewWillDisappear需要正确删除观察者,正如Ibrahim Ulukaya上面所描述的那样。
self.ref.child("messages").removeObserverWithHandle(_refHandle)
它应该在viewDidAppear中的原因是,当视图返回到顶部时,您可以重新开始观察表。需要在viewWillDisappear中删除观察者,这样当它不在屏幕上时,您没有视图响应观察者/通知,因为这违反了MVC规则。
希望这会有所帮助。我挣扎了一段时间。不确定Firebase团队是如何抓住这一点的。
答案 1 :(得分:0)
主要错误是在viewWillDisappear中删除了错误引用的观察者。 它应该是
self.ref.child("messages").removeObserverWithHandle(_refHandle)
代替。您还希望在viewWillAppear中删除removeAll后重新加载数据。
如果将它们移动到viewDidLoad和deAlloc,则每次都不需要删除对象和重新加载数据。
(我很快就会更新源代码。)