Timer闭包调用Singleton函数触发EXC_BAD_ACCESS(SIGBUS)崩溃求助
修复EXC_BAD_ACCESS(KERN_INVALID_ADDRESS)崩溃的方案
从崩溃日志来看,问题出在Swift String桥接为Objective-C对象时的引用计数操作(swift_unknownObjectRetain),触发场景是Timer回调中调用Core Data保存方法。结合你的代码,以下是具体修复措施:
1. 解决Timer的循环引用问题
Timer的闭包会默认捕获当前ViewController的self,形成Timer -> 闭包 -> self -> insertTimer -> Timer的循环引用,导致ViewController无法正常释放,后续回调时访问已释放的内存引发崩溃。修改代码添加弱引用:
private func startInsertTimer() { insertTimer?.invalidate() insertTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in guard let self = self else { return } // self已释放时直接退出 if let data = VDSUtil.shared.vdsString, let vin = VDSUtil.shared.vin { DBUtil.shared.saveVehicleStatus(data: data, vin: vin) } } }
同时在ViewController销毁时主动清理Timer:
deinit { insertTimer?.invalidate() insertTimer = nil }
2. 确保Core Data操作线程安全
Core Data的NSManagedObjectContext并非线程安全,即使当前回调在主线程,若存在多线程操作Context的情况,也可能导致内存异常。修改DBUtil的保存方法,强制在Context的队列中执行操作:
func saveVehicleStatus(data: String, vin: String) { let managedContext = AppDelegate.sharedAppDelegate.coreDataStack.managedContext managedContext.perform { let vStatus = VehicleStatus(context: managedContext) vStatus.data = data vStatus.vin = vin vStatus.date = Date() do { try managedContext.save() } catch { print("Core Data保存失败: \(error)") // 可添加日志上报逻辑 } } }
注意:如果你的saveContext方法内部有额外逻辑,也要确保它是线程安全的,避免跨线程调用。
3. 保证VDSUtil单例的线程安全
如果VDSUtil.shared的vdsString和vin属性在多线程下被读写,可能导致String内部结构损坏,桥接时触发内存错误。为这两个属性添加线程保护:
class VDSUtil { static let shared = VDSUtil() private let syncQueue = DispatchQueue(label: "com.yourapp.vds.sync") private var _vdsString: String? private var _vin: String? var vdsString: String? { get { syncQueue.sync { _vdsString } } set { syncQueue.sync { _vdsString = newValue } } } var vin: String? { get { syncQueue.sync { _vin } } set { syncQueue.sync { _vin = newValue } } } }
4. 增加字符串有效性校验
虽然已经用if let解包,但可以额外过滤空字符串或异常数据,减少潜在风险:
if let data = VDSUtil.shared.vdsString, !data.isEmpty, let vin = VDSUtil.shared.vin, !vin.isEmpty { DBUtil.shared.saveVehicleStatus(data: data, vin: vin) }
这些措施覆盖了内存引用、线程安全、数据有效性三个核心问题,应该能解决这次偶发的崩溃。
内容的提问来源于stack exchange,提问作者CaysRD
相关产品推荐
相关产品推荐

