withoutActuallyEscaping(_:do:)
声明
func withoutActuallyEscaping<ClosureType, ResultType>(
_ closure: ClosureType,
do body: (ClosureType) throws -> ResultType
) rethrows -> ResultType
返回值
body
闭包的返回值(如果有)。
参数
closure
在
body
闭包执行期间可转义的非转义闭包值。如果body
有返回值,则该值也用作withoutActuallyEscaping(_:do:)
函数的返回值。body
使用
closure
的可逃避副本作为其参数立即执行的闭包。
详述
您可以使用此函数调用一个 API,该 API 以一种不允许闭包在实践中转义的方式采用转义闭包。下面的示例演示了如何将 withoutActuallyEscaping(_:do:)
与使用转义闭包的两个常见 API 结合使用:惰性集合视图和异步操作。
以下代码声明了一个 allValues(in:match:)
函数,用于检查数组中的所有元素是否与谓词匹配。该函数不会像编写的那样编译,因为惰性集合的 filter(_:)
方法需要转义闭包。惰性集合不会持久化,因此 predicate
闭包实际上不会转义函数体;但是,它不能以这种方式使用。
func allValues(in array: [Int], match predicate: (Int) -> Bool) -> Bool {
return array.lazy.filter { !predicate($0) }.isEmpty
}
// error: closure use of non-escaping parameter 'predicate'...
withoutActuallyEscaping(_:do:)
提供了 predicate
的临时可逃逸副本,can
可用于调用惰性视图的 filter(_:)
方法。 allValues(in:match:)
的第二个版本编译没有错误,编译器保证 escapablePredicate
闭包不会持续超过对 withoutActuallyEscaping(_:do:)
的调用。
func allValues(in array: [Int], match predicate: (Int) -> Bool) -> Bool {
return withoutActuallyEscaping(predicate) { escapablePredicate in
array.lazy.filter { !escapablePredicate($0) }.isEmpty
}
}
异步调用是另一种类型的 API,通常会转义其闭包参数。以下代码声明了一个perform(_:simultaneouslyWith:)
函数,该函数使用调度队列同时执行两个闭包。
func perform(_ f: () -> Void, simultaneouslyWith g: () -> Void) {
let queue = DispatchQueue(label: "perform", attributes: .concurrent)
queue.async(execute: f)
queue.async(execute: g)
queue.sync(flags: .barrier) {}
}
// error: passing non-escaping parameter 'f'...
// error: passing non-escaping parameter 'g'...
perform(_:simultaneouslyWith:)
函数以使用.barrier
标志调用sync(flags:execute:)
方法结束,这会强制函数等到两个闭包都完成运行后再返回。尽管屏障保证两个闭包都不会逃逸函数,但 async(execute:)
方法仍然要求传递的闭包标记为 @escaping
,因此函数的第一个版本无法编译。要解决这些错误,您可以使用 withoutActuallyEscaping(_:do:)
获取可以传递给 async(execute:)
的 f
和 g
的副本。
func perform(_ f: () -> Void, simultaneouslyWith g: () -> Void) {
withoutActuallyEscaping(f) { escapableF in
withoutActuallyEscaping(g) { escapableG in
let queue = DispatchQueue(label: "perform", attributes: .concurrent)
queue.async(execute: escapableF)
queue.async(execute: escapableG)
queue.sync(flags: .barrier) {}
}
}
}
可用版本
相关用法
- Swift withTaskGroup(of:returning:body:)用法及代码示例
- Swift withThrowingTaskGroup(of:returning:body:)用法及代码示例
- Swift KeyValuePairs flatMap(_:)用法及代码示例
- Swift String.UTF8View first用法及代码示例
- Swift Result.Publisher zip(_:_:_:)用法及代码示例
- Swift Optional.Publisher reduce(_:_:)用法及代码示例
- Swift Int8 ~(_:)用法及代码示例
- Swift SetAlgebra isStrictSubset(of:)用法及代码示例
- Swift UInt +(_:)用法及代码示例
- Swift Array enumerated()用法及代码示例
- Swift FlattenSequence prefix(_:)用法及代码示例
- Swift Slice endIndex用法及代码示例
- Swift LazySequence split(maxSplits:omittingEmptySubsequences:whereSeparator:)用法及代码示例
- Swift MutableCollection partition(by:)用法及代码示例
- Swift ReversedCollection min(by:)用法及代码示例
- Swift RandomNumberGenerator用法及代码示例
- Swift Dictionary.Keys shuffled()用法及代码示例
- Swift AnySequence elementsEqual(_:)用法及代码示例
- Swift UInt &<<(_:_:)用法及代码示例
- Swift Optional.Publisher tryDrop(while:)用法及代码示例
- Swift DefaultIndices endIndex用法及代码示例
- Swift Substring.UnicodeScalarView insert(contentsOf:at:)用法及代码示例
- Swift LazyFilterSequence dropFirst(_:)用法及代码示例
- Swift LazySequence suffix(from:)用法及代码示例
- Swift ArraySlice starts(with:)用法及代码示例
注:本文由纯净天空筛选整理自apple.com大神的英文原创作品 withoutActuallyEscaping(_:do:)。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。