1

での作業を簡素化するために、プロトコル拡張を使用してプロトコルを定義しました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(     
    ^~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
4

1 に答える 1

1

Swift string Array is not compatible with CVarArgType... or [CVarArgType]

使ってみてください。

extension NSErrorConvertible where RawValue == Int {
    func generateError(format format: String) -> NSError {
        let error = NSError(domain: self.domain, code: self.rawValue, localizedDescription: format)
        return error
    }
    func generateError(args : CVarArgType...) -> NSError {
        let returnString = NSString(format: self.localizedDescription, arguments: getVaList(args)) as String
//        let returnString = withVaList(args) {
//            NSString(format: self.localizedDescription, arguments: $0)
//        } as String
        let error = generateError(format: returnString)
        return error
    }
}

enum DefaultEngineErrors: Int, NSErrorConvertible {
    case ImagesNotSupported
    case FooDoesNotHaveABar
    case FooWithMultiPar
    case NilBar

    var domain: String { return "DefaultEngineErrors" }

    var localizedDescription: String {
        switch self {
        case .ImagesNotSupported: return "%@: Images are not supported."
        case .FooDoesNotHaveABar: return "%@: Foo does not have a bar."
        case .FooWithMultiPar: return "%@:%@ Foo does not have a bar."
        case .NilBar:             return "%@: The bar is nil."
        }
    }
}

print(DefaultEngineErrors.FooDoesNotHaveABar.generateError("test"))
print(DefaultEngineErrors.FooWithMultiPar.generateError("test1","test2"))

これをチェック

于 2016-02-09T19:18:41.923 に答える