gpt4 book ai didi

Swift 通用函数不起作用

转载 作者:可可西里 更新时间:2023-11-01 01:06:29 24 4
gpt4 key购买 nike

因此,我在一个结构中创建了一个通用函数,该结构具有一些静态方法来帮助创建自定义 UIButton 等。所以我做了这段代码:

static func createAlertPicker<T: UIViewController where T: UIPickerViewDelegate, T: UIPickerViewDataSource>(#title: String, inout forPicker picker: UIPickerView, viewController: T) -> UIAlertController {
let alert = UIAlertController(title: title, message: "\n\n\n\n\n\n\n\n\n\n", preferredStyle: .Alert)
alert.view.tintColor = data.backgroundColor
picker = createPickerViewWithFrame(CGRectZero, delegate: viewController, dataSource: viewController, backgroundColor: UIColor.clearColor(), addToView: alert.view)
picker.frame = CGRect(x: 2, y: 70, width: 266, height: 162)
return alert
}

我在执行此操作时没有收到错误,但是在 ViewController 中调用此方法时,如下所示:

let alert = CreatorClass.createAlertPicker(title: "select sortage", forPicker: &self.pickerView!, viewController: self)

我收到一个疯狂的错误,告诉我 Type 'UIViewController' does not conform to protocol 'UIPickerViewDelegate'。尽管已实现,但这是 ViewController 的声明:

class PlayerDetails:UIViewController, UITableViewDataSource, UITableViewDelegate, UIPickerViewDelegate, UIPickerViewDataSource

顺便说一句,这个问题只发生在一个ViewController中,我调用了好几次。也许应该提到这行代码 (let alert = ...) 一开始甚至没有编译。

真的不明白这一点。感谢您的任何帮助! :]

最佳答案

是的,这个错误完全是谎言。

问题出在中间参数:&self.pickerView!

self.pickerView 是可选的。您的可选项包含一个引用,但展开该引用会将您返回引用的新副本按值。您无法访问可选内容中的原始引用。所以当你调用 ! 时,你会得到一个不可变的值。您不能更改它或分配给它,这意味着您不能将它作为 inout 参数传递。

这是一个更简单的例子:

let i: Int? = 5
func f(inout i: Int) { i = 6 }
f(&i!) // error: 'Int' is not convertible to '@lvalue inout $T3’

这是编译器将您从一个可能非常令人困惑的运行时错误中解救出来——如果传入并更改了值,它对您实际打算更改的值没有任何影响。只有临时副本会被更改。

这可能有点令人困惑,因为类是引用类型,所以您不习惯从值的角度来考虑它们。但是引用本身 是值。您从解包中得到的是引用的副本,而不是所引用内容的副本。

如果您将调用更改为如下所示,它应该可以工作:

if var picker = self.pickerView {
let alert = CreatorClass.createAlertPicker(title: "select sortage", forPicker: &picker, viewController: self)
// don’t forget to assign the value back...
self.pickerView = picker
}

此版本还有一个好处,即如果您在强制解包之前忘记将 forPicker 设置为一个值,则不会在火焰中爆炸。

但是,如果您使用 inout 只是为了返回一个新的选择器(不像您使用传入的值那样查看您的 createAlertPicker,只分配到它),那么为什么不放弃 inout 并使函数返回一对值:

static func createAlertPicker
<T: UIViewController where T: UIPickerViewDelegate>
(#title: String, viewController: T)
// return a tuple
-> (UIPickerView,UIAlertController) {
// etc…
var picker = createPickerViewWithFrame(CGRectZero, delegate: viewController, dataSource: viewController, backgroundColor: UIColor.clearColor(), addToView: alert.view)
picker.frame = CGRect(x: 2, y: 70, width: 266, height: 162)

return (picker, alert)
}


let (picker, alert) = CreatorClass.createAlertPicker(title: "select sortage”, viewController: self)
self.pickerView = picker

关于Swift 通用函数不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27654424/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com