での作業を簡素化するために、プロトコル拡張を使用してプロトコルを定義しましたNSError
。
protocol NSErrorConvertible: RawRepresentable {
var domain: String { get }
var localizedDescription: String { get }
}
extension NSErrorConvertible where RawValue == Int {
func generateError(parameters parameters: [String] = []) -> NSError {
let error = self.generateError(format: self.localizedDescription, parameters: parameters)
return error
}
func generateError(format format: String, parameters: [String] = []) -> NSError {
let description = String(format: format, arguments: parameters) // <-- BREAK
let error = NSError(domain: self.domain, code: self.rawValue, localizedDescription: description)
return error
}
}
extension NSError {
convenience init(domain: String, code: Int, localizedDescription: String) {
let userInfo = [NSLocalizedDescriptionKey : localizedDescription]
self.init(domain: domain, code: code, userInfo: userInfo)
}
}
プロトコルの使用方法は次のとおりです。
enum DefaultEngineErrors: Int, NSErrorConvertible {
case ImagesNotSupported
case FooDoesNotHaveABar
case NilBar
var domain: String { return "DefaultEngineErrors" }
var localizedDescription: String {
switch self {
case .ImagesNotSupported: return "%s: Images are not supported."
case .FooDoesNotHaveABar: return "%s: Foo does not have a bar."
case .NilBar: return "%s: The bar is nil."
}
}
}
プロトコル拡張メソッドの呼び出し方法は次のとおりです。
let error = DefaultEngineErrors.FooDoesNotHaveABar.generateError(parameters: ["\(foo.id)"])
このコードを実行すると、2 番目のgenerateError
拡張機能の説明を作成する行でデバッガーが中断し、デバッガー コンソールに次のメッセージが表示されます。
致命的なエラー: 異なるサイズの型間で unsafeBitCast を実行できません
への呼び出しをString(format:)
だけに置き換えるとformat
、すべて正常に動作することに注意してください。
Q: ここで行ったことの何が問題になっていますか?
これに加えて、プロトコル拡張のパラメーターを調べることができません。しようとすると、次のメッセージが表示されます。
(lldb) po format
error: <EXPR>:1:1: error: non-nominal type '$__lldb_context' (aka 'Self') cannot be extended
extension $__lldb_context {
^ ~~~~~~~~~~~~~~~
<EXPR>:15:5: error: value of type 'DefaultEngineErrors' has no member '$__lldb_wrapped_expr_54'
$__lldb_injected_self.$__lldb_wrapped_expr_54(
^~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~