final class TestVC: UIViewController {
var usersFooter: Footer!
var groupsFooter: Footer!
override func viewDidLoad() {
super.viewDidLoad()
bind(footer: &usersFooter)
}
func bind(footer: inout Footer) {
footer = Footer(style: .autoFooter, height: 57) {
// doing something
}
}
}
知道Footer是什么:
final class Footer: RefreshView {
private var loader: MDCActivityIndicator!
override public init(style: Style, height: CGFloat, action: @escaping () -> Void) {
// initializing and doing something with loader
super.init(style: style, height: height, action: action)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
我明白了:
无法传递类型'页脚'的不可变值作为inout参数
如何在其功能中传递TestVC实例的页脚并能够初始化它们? 为什么页脚是不可变的(声明为var)?
答案 0 :(得分:1)
这是因为
var someVar: Footer!
不定义类型为Footer
的变量,而是定义隐式展开的Optional<Footer>
类型的变量。代码:
var someFooter: Footer!
bind(footer: &someFooter)
在逻辑上等同于
var someFooter: Footer?
guard let tempFooter = someFooter? else { fatalError() }
bind(footer: &tempFooter)
正如您所看到的,tempFooter
是一个let,所以它不能作为inout变量传递,即使它可以,结果也会被抛弃。
您可以通过以下三种方式之一解决此问题:
使参数绑定可选项,例如func bind(footer: inout Footer?)
或使用Martin's syntax使其隐式可选。
强行打开自己:
var unwrapped: Footer = someFooter
bind(footer: unwrapped)
someFooter = unwrapped
重新设计API。看来你在bind
函数中做的第一件事是用新初始化的页脚覆盖旧页脚。所以不要使用inout参数,返回你想要的值,即
func bind() -> Footer
{
var theFooter = Footer(...) { ... }
// do stuff
return theFooter
}
someFooter = bind()
我认为在这种情况下,最后一个选项是最好的。
答案 1 :(得分:0)
像这样写bind
方法。它将解决您的错误。
func bind(footer: inout Footer!) {
footer = Footer(style: .autoFooter, height: 57) {
// doing something
}
}
似乎 inout 认为Footer&amp;页脚!是不同的。如上所述更新方法或更改下面给出的声明。
var userFooter: Footer
我不知道确切的原因,但我们得到的错误令人困惑。