Я переписываю некоторый код, чтобы добавлять задания в массив замыканий, а не выполнять их напрямую:
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, поэтому все рекомендации были с благодарностью приняты. Спасибо!
Список захвата, такой как [someObject]
, на самом деле является синтаксическим сахаром для [someObject = someObject]
, где правая часть может быть произвольным выражением, которое привязывается к новой константе при формировании замыкания.
Поэтому один из вариантов - написать свой пример как:
jobsArray.append { [property = someObject!.property] in
doExpensiveOperation(property)
}
@NRitH, это не массив, это список захвата. См. «Определение списка захвата» в docs.swift.org/swift-book/LanguageGuide/….