【发布时间】:2017-05-09 01:22:39
【问题描述】:
我有大量适用于 Mac OS 10.11 及更高版本的 Swift 3 代码(使用 Xcode 8.2.1)。有许多进程,其中有一个 GUI 应用程序和一个后台服务。这两个都使用自定义的URLProtocol,它在框架中实现(由应用程序和服务导入)。该协议有时可能会生成符合Error 的enum 实例,它会适当地捕获和处理这些实例(通常通过使用URLProtocolClient 将它们扔到试图发出请求的URLSession)。
- 当没有错误时,应用和服务都可以正常工作。
- 当出现错误时,应用可以正常工作(嗯,正如预期的那样)。
- 出现错误时,服务会崩溃。
通过调试器发现当Error 被运行时自动转换为NSError 时,就会发生这种崩溃。我在我的代码中明确添加了这个演员,果然,我得到了同样的崩溃,现在在那一行。
我看到了Swift 3.1: Crash when custom error is converted to NSError to access its domain property,但这里不适用:
- 那里的解决方案 - 将
Error扩展到CustomNSError(以及LocalizedError以进行良好的衡量)并实现相关属性 - 没有帮助。 - 在获得
domain后发生崩溃;据我所知,这对我来说不是问题。 - 可能相关:那是在 iOS 上,而不是在 Mac 上。
已经尝试了该问题的唯一列出的解决方案,我有点不知所措。我已经调试了好几个小时了,但它似乎发生在 dyld 的深处。
代码:
enum CrowbarProtocolError: Error {
case FailedToCreateSocket;
case PathTooLong;
case NonSocketFile;
case SocketNotFound;
...
case UnrecognizedError(errno: Int32);
}
extension CrowbarProtocolError: LocalizedError {
public var errorDescription: String? {
return "Some localized description"
}
}
extension CrowbarProtocolError: CustomNSError {
public static var errorDomain: String {
return "Some Domain Name"
}
public var errorCode: Int {
return 204 //Should be your custom error code.
}
public var errorUserInfo: [String: Any] {
return ["WTF": "Swift?"];
}
}
...
open class CrowbarUrlProtocol: URLProtocol {
...
override open func startLoading() {
do {
let sockHandle = try CrowbarUrlProtocol.openSocket();
let req = try buildRequestData();
sockHandle.write(req);
NotificationCenter.default.addObserver(
self,
selector: #selector(self.readCompleted),
name: .NSFileHandleReadToEndOfFileCompletion,
object: nil);
sockHandle.readToEndOfFileInBackgroundAndNotify();
} catch let err {
Log.warn("CrowbarUrlProtocol request failed with error \(err)");
// -- In the background service, THIS LINE CRASHES! --
let err2 = err as NSError;
Log.warn("As NSError: \(err2)");
// -- Without the explicit cast, it crashes on this line --
self.client?.urlProtocol(self, didFailWithError: err);
}
}
...
}
我解决这个问题的一个想法就是使用NSErrors 做所有事情(或尽可能多地),因为如果不需要将Error 转换为NSError,那么任何导致这次崩溃的事情都不会发生。不知道它是否会起作用,但似乎值得一试......
【问题讨论】:
标签: swift macos swift3 crash nserror