使用闭包语法快速声明函数

时间:2018-08-26 07:20:43

标签: swift closures

通读Advanced Swift并给出以下示例

“在Swift中,您可以通过两种方式定义函数。一种是使用func关键字。另一种方法是使用闭包表达式。考虑这个简单的函数将数字加倍:

func doubler(i: Int) -> Int {
    return i * 2
}
[1, 2, 3, 4].map(doubler) // [2, 4, 6, 8]

这是使用闭包表达式语法编写的相同函数。和以前一样,我们可以将其传递给地图:

let doublerAlt = { (i: Int) -> Int in return i*2 }
[1, 2, 3, 4].map(doublerAlt) // [2, 4, 6, 8]”

我正在玩这个游戏,并在集合视图单元格类中编写了以下代码。

let setupView = {(label: UILabel) in
    addSubview(label)
    label.topAnchor.constraint(equalTo: topAnchor).isActive = true
    label.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
    label.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    label.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
}

func setupViews(label: UILabel) {
    addSubview(label)
    label.topAnchor.constraint(equalTo: topAnchor).isActive = true

    label.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
    label.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    label.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
}

最上面的一个给我错误,但是最下面的一个使用func关键字可以正常工作。我认为他们俩都应该工作。我想知道是否有人可以解释。

1 个答案:

答案 0 :(得分:3)

闭包是 closed ,因此默认情况下,您无法访问闭包内部的闭包外部内容。

self是闭包之外的内容,因此您需要捕获才能在闭包内使用它。您没有捕获self,因此无法调用self.addSubView

self是一种特殊情况。要捕获它,只需将其明确写出即可:

self.addSubView(label)
// and
self.topAnchor
self.leftAnchor
// etc

但是,这将导致保留周期。闭包一直都强烈引用self,而self一直都强烈引用闭包。两者都不能释放。因此,您应该使用self捕获unowned

lazy var setupView = {[unowned self] (label: UILabel) in
    self.addSubview(label)
    label.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
    label.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
    label.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
    label.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
}