在Swift中为闭包捕获对象的属性

时间:2019-05-28 13:41:39

标签: swift

我正在重写一些代码,以将作业追加到闭包数组中,而不是直接执行它们:

var someObject: SomeType?
var jobsArray: [() -> ()] = []

// before rewriting
doExpensiveOperation(someObject!.property)

// 1st attempt at rewriting
jobsArray.append {
    doExpensiveOperation(someObject!.property)
}

但是,由于在执行闭包之前someObject的值可能会发生变化,因此我现在添加如下的闭包列表:

// 2nd attempt at rewriting
jobsArray.append { [someObject] in
    doExpensiveOperation(someObject!.property)
}

希望然后,例如,如果在闭包执行之前将someObject设置为nil,则闭包仍将访问预期的实例。

但是,处理闭包执行前.property的值可能发生变化的最巧妙方法是什么?有没有比这更好的方法了?

// 3rd attempt at rewriting
let p = someObject!.property
jobsArray.append { 
    doExpensiveOperation(p)
}

我不太喜欢这种解决方案,因为这意味着更改原始代码行。我更愿意这样做,但是不起作用:

// 4th attempt at rewriting
jobsArray.append { [someObject!.property] in
    doExpensiveOperation(someObject!.property)
}

Swift很新,因此所有指导都深表感谢。谢谢!

1 个答案:

答案 0 :(得分:3)

诸如[someObject]之类的捕获列表实际上是[someObject = someObject]的语法糖,其中右侧可以是任意表达式,在形成闭包时绑定到新常数。

因此,一种选择是将示例编写为:

jobsArray.append { [property = someObject!.property] in
  doExpensiveOperation(property)
}