iOS Delegate调用双报错:可选类型不能作布尔值,解包类型不匹配
看起来你在iOS开发中踩了代理方法调用的常见坑,我来帮你拆解问题根源和解决办法:
为什么会出现第一个报错?
你的代理属性是用weak修饰的,而在Swift中,weak变量必须是可选类型——因为被weak引用的对象可能随时被释放变成nil,所以delegate的实际类型是ManageCaptureVCDelegate?(可选的协议类型)。
当你直接写if delegate.selectedInterfaceOrientationIsLandscape()时,编译器会报错:因为你没有处理delegate为nil的情况,而且可选对象的方法调用必须通过可选链(?.)来触发,否则编译器不允许这种不安全的操作。
强制解包后为什么还是错?
你提到强制解包后出现'() -> Bool' is not convertible to 'Bool'的错误,这大概率是因为你写了类似这样的错误代码:
// 错误写法:只解包了函数本身,没有调用它 if delegate!.selectedInterfaceOrientationIsLandscape { // ... }
这里delegate!.selectedInterfaceOrientationIsLandscape拿到的是一个函数类型() -> Bool,而不是函数执行后的Bool返回值。你漏掉了调用函数的括号(),所以编译器无法把函数类型转换成布尔值。
正确的解决方法有这几种:
1. 可选链+nil合并运算符(最推荐,安全简洁)
用?.调用代理方法,返回的是Bool?(如果delegate为nil则返回nil),再用??给一个默认值(比如默认返回false):
let isLandscape = delegate?.selectedInterfaceOrientationIsLandscape() ?? false if isLandscape { // 执行横屏相关逻辑 }
2. 先解包代理对象,再调用方法
如果你需要明确区分delegate为nil和方法返回false的情况,可以先绑定可选的delegate:
if let validDelegate = delegate { let isLandscape = validDelegate.selectedInterfaceOrientationIsLandscape() if isLandscape { // 横屏逻辑 } else { // 方法返回false的逻辑 } } else { // delegate不存在的逻辑 }
3. 强制解包(仅在确定delegate一定存在时使用)
只有当你能100%保证delegate永远不会为nil时,才可以用强制解包,但这种写法有崩溃风险,不推荐:
// 注意一定要加()调用函数,获取返回值 if delegate!.selectedInterfaceOrientationIsLandscape() { // 横屏逻辑 }
关键知识点回顾
- Weak修饰的代理必须是可选类型,避免循环引用和野指针问题。
- 调用可选对象的方法时,必须用可选链
?.或者先解包,否则编译器会报错。 - 函数类型(比如
() -> Bool)和它的返回值(Bool)是完全不同的类型,一定要加()来执行函数拿到返回值。
内容的提问来源于stack exchange,提问作者Chewie The Chorkie

