导航控制器操作后App崩溃及相机报错问题咨询
iOS开发问题解答
1. 导航控制器dismiss视图后App崩溃
这种崩溃大多和内存管理、调用时机有关,给你梳理几个高频触发场景:
- 强引用循环导致野指针访问:如果被dismiss的视图控制器里有闭包(比如网络请求回调、定时器)没加
weak self/unowned self,会让控制器无法被正常释放,后续闭包执行时访问已销毁的资源就会崩溃。赶紧检查所有闭包的捕获列表,斩断强引用链。 - 错误的dismiss时机:比如在视图过渡动画(present/unwind)还没完成时重复调用
dismiss(animated:completion:),或者当前调用dismiss的控制器根本不是被presented的那个(比如导航栈里的子控制器直接调用dismiss)。可以通过presentedViewController属性确认当前控制器是否处于可dismiss状态。 - dismiss后访问已释放控件:如果在dismiss的completion回调或其他地方,还在操作被dismiss控制器的UI控件(比如tableView、按钮),这些控件已经随控制器销毁,访问它们必然触发崩溃。
2. 导航控制器unwind期间是否可以reload cell?
非常不建议这么做。Unwind segue本质是导航栈的回退过程,此时目标视图控制器的视图层级还处于过渡状态(比如正在移除栈内控制器、视图布局未完全完成)。如果在unwind过程中(比如unwind的IBAction里直接调用tableView.reloadData()),很容易导致tableView布局混乱,甚至因视图状态不稳定触发崩溃。
正确的做法是把reload操作放在unwind完成后:
- 若用代码触发unwind,可以在completion回调里执行reload;
- 或者在目标视图控制器的
viewDidAppear(_:)方法里做reload,此时视图已完全显示,状态稳定。
3. 执行segue后点击相机按钮崩溃,报错“No active and enabled video connection”
这个错误来自AVFoundation框架,说明你的AVCaptureSession没有建立有效的视频输入输出连接,常见原因有这些:
- Segue后相机会话未正确初始化:Segue跳转后的新视图控制器里,
AVCaptureSession的配置(添加输入设备、输出对象)没完成,或者没调用startRunning(),点击相机按钮时自然找不到有效视频连接。检查新控制器的viewDidLoad/viewWillAppear里的相机初始化代码,确保输入输出都正确添加到会话,且会话已启动。 - 切换相机时未正确更新会话连接:flip按钮能切换相机,但切换过程中可能没先移除旧的
AVCaptureDeviceInput就直接加新输入,导致会话连接混乱。正确流程是:先调用session.stopRunning(),移除旧输入,添加新输入,再重启会话,而且这些配置操作必须在串行队列里执行(AVCaptureSession的配置不能在主线程瞎搞,避免阻塞)。 - 会话状态异常:Segue过程中会话可能被意外暂停或释放,导致点击相机按钮时会话处于无效状态。可以在相机按钮的点击事件里先检查
session.isRunning和session.inputs是否为空,再执行后续操作。 - 权限排查(虽少见但别漏):如果相机权限没正确获取,哪怕flip按钮能触发切换,实际相机设备也无法被访问,会导致连接失败。去系统设置里确认App的相机权限是否开启,代码里也要确保拿到权限后再初始化相机会话。
内容的提问来源于stack exchange,提问作者TheRedCamaro3.0
相关产品推荐
相关产品推荐

