【发布时间】:2019-05-08 19:13:11
【问题描述】:
在一个 UIViewController (rolePageController) 中,我配置了另一个 UIViewController (drawerController),并从角色页面传递了 2 个 UIView,这将成为抽屉控制器配置的一部分。只要drawerController 尝试从rolePageController 访问IBOutlet 视图,它就会崩溃并出现EXC_BAD_ACCESS(代码=EXC_I386_GPFLT)。
在第一个 VC (rolePageController) 中,这里是 IBOutlets:
@IBOutlet var rolePageDrawerView: UIView!
@IBOutlet var rolePageContentView: UIView!
在 rolePageController.viewDidLoad() 中,我调用了 drawerController.configureDrawer(...):
override func viewDidLoad() {
super.viewDidLoad()
//other stuff happens here
let drawerController = UIStoryboard(name: "StoryboardName", bundle: nil).instantiateViewController(withIdentifier: "drawerController") as! DrawerViewController
drawerController.configureDrawer(drawerContainerView: self.rolePageDrawerView, overlaidView: self.rolePageContentView)
//other stuff here
}
DrawerViewController 协议定义为:
protocol DrawerViewController where Self: UIViewController {
func configureDrawer(drawerContainerView: UIView, overlaidView: UIView)
}
这里是 configureDrawer(...) 函数的代码:
private var drawerParentView: UIView!
private var overlaidByDrawerView: UIView!
func configureDrawer(drawerContainerView: UIView, overlaidView: UIView) {
self.drawerParentView = drawerContainerView
self.overlaidByDrawerView = overlaidView
}
在调试器中注意到被调用的drawerController实例与接收调用的self实例不匹配。这是将要调用的实例的地址:
这是我进入通话时实例的地址:
调用前drawerController的地址不是我进入调用时self的地址。那不应该发生。
我创建了一个简化的项目来重现 https://github.com/ksoftllc/DynamicStackBufferOverflow 的崩溃。
解决方案 解决方案原来是从 DrawerViewController 协议中删除 where 子句。
protocol DrawerViewController where Self: UIViewController {
func configureDrawer(drawerContainerView: UIView, overlaidView: UIView)
}
【问题讨论】:
-
尝试将内容从 viewDidLoad 移动到 viewDidAppear。听起来它被调用时可能不会在屏幕上绘制。此外,如果某个东西后面有一个
!,它就必须在那里,所以它不应该是弱的。不知道为什么 Xcode 开箱即用,但不要隐式展开可选的弱引用。 -
@ChuckKrutsinger 你想分享一个有问题的示例项目吗?您是否尝试重新启动 Xcode、删除应用并重新安装?
-
是的,一个示例项目会有所帮助。
-
这不是
drawerController的属性的一些无效初始值吗?例如一些旧的故事板连接? -
解包隐式解包的可选项(如
rolePageDrawerView)不会触发EXC_BAD_ACCESS。在发布版本中,它触发EXC_BAD_INSTRUCTION,在调试版本中,它首先在_swift_runtime_on_report中停止,然后(如果您继续执行)触发EXC_BAD_INSTRUCTION。所以问题可能不是由于意外的 nil。
标签: ios swift uiviewcontroller exc-bad-access swift-protocols