iOS 15 Beta 5(19A5318f)下NSRunLoop调用run方法崩溃如何解决?
iOS15 Beta5 专属NSThread子线程RunLoop崩溃分析与修复
崩溃根因
- 该崩溃是iOS 15 Beta5(19A5318f)专属的系统底层bug,仅在该测试版本出现,后续iOS15正式版已经修复该问题。
- 触发逻辑:你自定义了常驻Socket子线程并启动RunLoop后,其他线程通过
performSelector:onThread:withObject:waitUntilDone:系列方法向该子线程投递任务时,系统内部的_NSThreadPerformInfo对象存在过度释放的内存管理缺陷,导致RunLoop处理完任务调用该对象的dealloc方法时触发野指针访问,抛出EXC_BAD_ACCESS异常,和你提供的崩溃栈特征完全匹配。
修复方案
方案1:替换线程间通信方式(最稳妥)
弃用performSelector:onThread:系列方法投递任务,改为给Socket线程绑定专属串行DispatchQueue,所有需要在Socket线程执行的任务都通过GCD派发到该队列,完全规避系统内存缺陷:
// 初始化阶段创建Socket专属队列,可指定目标队列优先级匹配原线程优先级 dispatch_queue_t socketQueue = dispatch_queue_create("com.yourapp.MyClassSocketQueue", DISPATCH_QUEUE_SERIAL); // 投递任务示例 dispatch_async(socketQueue, ^{ // 原有需要在Socket线程执行的逻辑 });
方案2:修改RunLoop启动逻辑
如果需要保留原有NSThread+RunLoop的架构,将无超时的run方法替换为带超时的循环调用逻辑,避免RunLoop长期陷入系统内核处理:
[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode]; // 替换原有的[[NSRunLoop currentRunLoop] run] while (self.isSocketThreadAlive) { // 新增自定义的线程存活控制标识 @autoreleasepool { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:3.0]]; } }
方案3:版本适配
由于该问题仅存在于iOS15 Beta5版本,可以增加系统版本判断,仅在该版本下启用上述规避逻辑,其他版本保留原有实现即可。
内容的提问来源于stack exchange,提问作者qing
相关产品推荐
相关产品推荐

