使用JSQMessagesViewController执行Segue触发SIGABRT错误求助
SIGABRT Crash When Seguing From JSQMessagesViewController
我之前在使用JSQMessagesViewController结合Firebase做聊天功能时,也碰到过一模一样的Segue崩溃问题。结合你提供的代码来看,最可能的原因是Firebase的观察者没有被正确移除,导致内存引用异常,最终触发SIGABRT错误。下面是具体的排查和解决步骤:
1. 移除Firebase实时数据库的观察者
你在viewDidLoad里调用了query.observe(.childAdded),这个方法会返回一个DatabaseHandle,用来标记当前的监听任务。如果不手动移除这个监听,当你离开聊天VC时,Firebase仍然会持有VC的引用(哪怕你用了[weak self]),引发循环引用或者野指针问题。
解决方法:
- 首先在VC类里添加一个属性保存观察者句柄:
private var messageObserverHandle: DatabaseHandle?
- 然后在
viewDidLoad中把observe的返回值赋值给这个属性:
messageObserverHandle = query.observe(.childAdded, with: { [weak self] snapshot in if let data = snapshot.value as? [String: String], let id = data["sender_id"], let name = data["name"], let text = data["text"], !text.isEmpty { if let message = JSQMessage(senderId: id, displayName: name, text: text) { self?.messages.append(message) self?.finishReceivingMessage() } } })
- 最后在VC的
deinit方法里移除观察者:
deinit { if let handle = messageObserverHandle { Constants.refs.databaseChats.removeObserver(withHandle: handle) } }
2. 停止JSQMessagesViewController的异步UI操作
JSQMessagesViewController有自己的消息处理生命周期,比如finishReceivingMessage会触发collectionView的刷新。如果VC已经出栈,再调用这个方法会导致UIKit操作异常。
你可以在viewWillDisappear里停止相关操作:
override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) self.stopReceivingMessage() }
3. 排查Segue和目标VC的配置问题
如果上面两步还没解决,检查一下:
- Storyboard里的Segue标识符是否和代码里的
performSegue(withIdentifier:sender:)完全匹配 - 目标视图控制器有没有未连接的IBOutlet,或者在
viewDidLoad里有没有未初始化就使用的属性 - 导航栏返回按钮的Segue是否正确关联了目标VC
调试小技巧
打开Xcode的断点导航栏(Command+8),添加一个All Exceptions断点。这样崩溃时Xcode会停在具体触发错误的代码行,能帮你快速定位问题(比如是Firebase回调里的UI操作,还是Segue时的VC初始化问题)。
内容的提问来源于stack exchange,提问作者Keenan Warouw
相关产品推荐
相关产品推荐

