在DispatchQueue的捕获块上,我在Swift 4和Swift 4.2上都遇到了细分错误。
我试图为DispatchQueue的转义参数提供一个捕获块,以确保传递给被调用闭包的对象在被调用时仍处于 Activity 状态。
代码看起来像这样:
import Foundation
struct Response {
let outcome: String?
}
enum NotEvenError: Error {
case notEven
}
struct IsEvenService {
typealias SuccessCallback = (Response) -> Void
typealias FailureCallback = (Error?) -> Void
func perform(success: @escaping SuccessCallback, failure: @escaping FailureCallback) {
let number = Int.random(in: 0 ... 10)
if number%2 == 0 {
let outcome = Response(outcome: "it is")
success(outcome)
} else {
failure(NotEvenError.notEven)
}
}
}
func runTest(success: @escaping (Response) -> Void, failure: @escaping (Error?) -> Void) {
let service = IsEvenService()
service.perform(success: { (response) in
if response.outcome != nil {
DispatchQueue.main.async { [resp = response] in
success(resp)
}
}
},
failure: { (error) in
DispatchQueue.main.async { [err = error] in
failure(err)
}
})
}
问题部分如下:
DispatchQueue.main.async { [err = error] in
failure(err)
}
这是一个示例文件,可以在命令行中通过swiftc调用轻松地进行验证。
结果如下:
Apple Swift version 4.2 (swiftlang-1000.11.37.1 clang-1000.11.45.1)
Target: x86_64-apple-darwin17.7.0
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c -primary-file test.swift -target x86_64-apple-darwin17.7.0 -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -color-diagnostics -module-name test -o /var/folders/fn/wh62twgj54180b7x1dx9j6080000gp/T/test-d0f7f4.o
0 swift 0x000000010720964a PrintStackTraceSignalHandler(void*) + 42
1 swift 0x0000000107208dfe SignalHandler(int) + 302
2 libsystem_platform.dylib 0x00007fff7ac3ff5a _sigtramp + 26
3 libsystem_platform.dylib 0x00007ffeec7e0000 _sigtramp + 1908015296
4 swift 0x0000000103eef293 swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 6531
5 swift 0x0000000103ea826e swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 462
6 swift 0x0000000103e0be14 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*)::$_1::operator()(swift::SILFunction*) const + 516
7 swift 0x0000000103e0b142 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 1042
8 swift 0x0000000103e1501b swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 939
9 swift 0x0000000103e16bd5 swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool) + 1333
10 swift 0x00000001034983fe performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 28990
11 swift 0x000000010348ddc5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 7717
12 swift 0x0000000103433a35 main + 1349
13 libdyld.dylib 0x00007fff7a931015 start + 1
14 libdyld.dylib 0x000000000000000f start + 2238509051
Stack dump:
0. Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c -primary-file test.swift -target x86_64-apple-darwin17.7.0 -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -color-diagnostics -module-name test -o /var/folders/fn/wh62twgj54180b7x1dx9j6080000gp/T/test-d0f7f4.o
1. While emitting SIL for 'runTest(success:failure:)' at test.swift:26:1
2. While silgen emitFunction SIL function "@$S4test7runTest7success7failureyyAA8ResponseVc_ys5Error_pSgctF".
for 'runTest(success:failure:)' at test.swift:26:1
<unknown>:0: error: unable to execute command: Segmentation fault: 11
<unknown>:0: error: compile command failed due to signal 11 (use -v to see invocation)
是否可以安全地假设,如果我不传递捕获块,则在执行闭包时将保留该对象?
如果执行以下操作,它将编译:
let uselessTempError = error
DispatchQueue.main.async { [err = uselessTempError] in
failure(err)
}
最佳答案
您不需要[err = error]
部分。以下块将对错误有强烈的参考:
DispatchQueue.main.async {
failure(error)
}