Swift用DispatchQueue.concurrentPerform操作数组触发_ArrayBuffer崩溃无法复现
崩溃原因
Swift 中的 Array 是值类型,不具备线程安全特性,同一时间如果有多个线程同时对 Array 执行读、写操作,会破坏底层_ArrayBuffer的内存结构,引发野指针、内存管理异常类崩溃。你使用DispatchQueue.concurrentPerform分发的任务会在多线程并行执行,多个线程同时调用addLessonIfNeeded方法时,会同时遍历、修改arrayLessons,恰好触发了这个并发读写问题。这类线程时序问题本身是非必现的,所以你在本地测试很难复现,只有在设备负载较高、刚好触发了并发读写冲突的时序才会崩溃。
修复方案
使用串行队列做所有操作的同步保护,保证任意时间只有一个线程可以访问arrayLessons,彻底避免并发读写冲突。
代码修改示例
首先新增一个专门用于数据保护的串行队列:
// 新增私有串行队列,仅用于处理arrayLessons的读写操作 private let dataSafeQueue = DispatchQueue(label: "com.yourapp.PPNotesManager.dataQueue")
修改addLessonIfNeeded方法,将所有对arrayLessons的读写逻辑都放到串行队列中执行:
func addLessonIfNeeded(lesson: NotesLessonDataModel) { guard lesson.isValid() else { return } // 同步执行保证操作顺序,不会出现读写冲突 dataSafeQueue.sync { [weak self] in guard let self = self else { return } // 查重逻辑 let alreadyExists = self.arrayLessons.contains { $0.id == lesson.id } if !alreadyExists { self.arrayLessons.append(lesson) } } }
注意:后续你在其他地方需要读取、修改
arrayLessons时,也必须将操作放到同一个dataSafeQueue中执行,否则依然会存在并发风险。
内容的提问来源于stack exchange,提问作者newbision
相关产品推荐
相关产品推荐

