无法将'() -> _'类型的值转换为指定类型UIImageView

问题描述 投票:0回答:3

我正在尝试使 UIImage 视图可点击,但我没有运气。完成这项任务的最佳方式是什么?我收到的错误是“无法将类型 '() -> _' 的值转换为指定类型 'UIImageView'”。

lazy var profileImageView: UIImageView = {
     let imageView = UIImageView()
     imageView.image = UIImage(named: "ic_file_upload_white_48pt")
     imageView.translatesAutoresizingMaskIntoConstraints = false
     imageView.contentMode = .scaleAspectFill

     imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleSelectorProfileImage)))
     imageView.isUserInteractionEnabled = true
     return imageView
 }
ios swift uiimageview
3个回答
67
投票

您告诉编译器您想要使

profileImageView
包含一个闭包。如果您希望 profileImageView 包含该闭包的results,则需要在后面添加括号以调用闭包:

lazy var profileImageView: UIImageView = {
  //your code here
  return imageView
}()

注意结束后的括号。第一次引用变量时,会将调用闭包的结果分配给变量

profileImageView

编辑:

任何时候你看到某种类型的

(<something>) -> type
都是一个闭包。
->
位将参数与返回类型分开。 Swift 的错误消息可能很难解读,但这是一个线索,表明您返回的是一个闭包,而不是预期的任何内容。

编辑#2:

请注意,在 Swift 中,有 2 个与闭包定义的变量相关的类似构造:计算属性和惰性变量。

计算属性

计算属性声明为

var computed: type { closure_returning_result }

计算属性中没有等号。每次您从计算属性中请求一个值时,闭包代码都会运行,并且闭包的返回值是该属性的新值。

惰性变量:

惰性变量看起来像这样:

lazy var lazy: type = expression_returning_result

表达式通常是一个闭包,但并非必须如此。惰性 var 的常见形式将使用闭包,如下所示:

lazy var lazy: type = { closure_returning_result }()

惰性变量的声明中有一个等号。如果使用闭包给lazy var赋值,则需要在闭包后面添加括号,这样lazy var被分配的是闭包的返回值,而不是闭包本身。当 @jameel 忘记了他的代码中的右括号时,这个线程就出现了。

考虑以下代码:

var counter = 1

var computed: Int  {
    counter += 1
    return counter
}

lazy var lazy: Int = {
    counter += 1
    return counter
}()

print("lazy = \(lazy)")
print("lazy = \(lazy)")
print("lazy = \(lazy)")

print("computed = \(computed)")
print("computed = \(computed)")
print("computed = \(computed)")

打印输出:

lazy = 2
lazy = 2
lazy = 2
computed = 3
computed = 4
computed = 5

请注意,lazy var 的值不会改变,但计算属性的值会改变。这是它们之间的主要区别。

惰性变量在您第一次请求它时就会被评估,并且该值“粘住”。提供该值的表达式/闭包在您请求之前不会运行,并且仅运行一次。

相比之下,计算属性始终使用闭包,每次请求计算属性的值时,都会执行闭包。

编辑#3:(9/28/2023)

另请注意,惰性变量在您首次引用之前不会被初始化,这一事实可能会产生后果。

如果你颠倒了上面测试代码的顺序:

print("computed = \(aFoo.computed)")
print("computed = \(aFoo.computed)")
print("computed = \(aFoo.computed)")

print("lazy = \(aFoo.lazy)")
print("lazy = \(aFoo.lazy)")
print("lazy = \(aFoo.lazy)")

print("computed = \(aFoo.computed)")

print("lazy = \(aFoo.lazy)")

print("computed = \(aFoo.computed)")

输出将是

computed = 2
computed = 3
computed = 4
lazy = 5
lazy = 5
lazy = 5
computed = 6
lazy = 5
computed = 7

使用该示例代码,在调用计算属性 3 次之前,我们不会引用

lazy
。一旦我们引用
lazy
,它就会递增
counter
并将该结果永远保存为新值。

如果我们再次引用

computed
,它会再次增加计数器。

在代码执行的生命周期内,

lazy
的值固定在 5。


6
投票

看起来像是语法问题,请尝试

func profileImageView() -> UIImageView {
        let imageView = UIImageView()
        imageView.image = UIImage(named: "ic_file_upload_white_48pt")
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.contentMode = .scaleAspectFill

        imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleSelectorProfileImage)))
        imageView.isUserInteractionEnabled = true
        return imageView
}

6
投票

您应该在计算属性末尾添加括号才能执行它。

lazy var profileImageView: UIImageView = {
     let imageView = UIImageView()
     imageView.image = UIImage(named: "ic_file_upload_white_48pt")
     imageView.translatesAutoresizingMaskIntoConstraints = false
     imageView.contentMode = .scaleAspectFill

     imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleSelectorProfileImage)))
     imageView.isUserInteractionEnabled = true
     return imageView
 }()
© www.soinside.com 2019 - 2024. All rights reserved.