iOS之swift中的错误处理

434 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

错误处理

为了使我们自己封装的JSON解析更加好用,除了对正常返回的处理,还需要对其中的错误进行处理,那么如何在swift中正确的表达错误呢?
首先,Swift中,提供了Error协议标识当前应用程序发生错误的情况,其中Error的定义如下

public protocol Error {
}

Error是一个空协议,其中没有任何实现,这也就意味着你可以遵守该协议,然后自定义错误类型。所以不管是我们的struct、Class、enum,我们都可以遵循这个Error来表示一个错误

所以接下来,对我们上面封装的JSON解析修改其中的错误处理

  • 定义一个JSONMapError错误枚举,将默认实现的print替换成枚举类型
//定义错误类型
enum JSONMapError: Error{
    case emptyKey
    case notConformProtocol
}

//1、定义一个JSON解析协议
protocol CustomJSONMap {
    func jsonMap() -> Any
}
//2、提供一个默认实现
extension CustomJSONMap{
    func jsonMap() -> Any{
        let mirror = Mirror(reflecting: self)
        //递归终止条件
        guard !mirror.children.isEmpty else {
            return self
        }
        //字典,用于存储json数据
        var keyValue: [String: Any] = [:]
        //遍历
        for children in mirror.children {
            if let value = children.value as? CustomJSONMap {
                if let keyName = children.label {
                    //递归
                    keyValue[keyName] = value.jsonMap()
                }else{
                    return JSONMapError.emptyKey
                }
            }else{
                return JSONMapError.notConformProtocol
            }
        }
        return keyValue
    }
}

但是这里有一个问题,jsonMap方法的返回值是Any,我们无法区分返回的是错误还是json数据,那么该如何区分呢?即如何抛出错误呢?在这里可以通过throw关键字(即将Demo中原本return的错误,改成throw抛出)

//2、提供一个默认实现
extension CustomJSONMap{
    func jsonMap() -> Any{
        let mirror = Mirror(reflecting: self)
        //递归终止条件
        guard !mirror.children.isEmpty else {
            return self
        }
        //字典,用于存储json数据
        var keyValue: [String: Any] = [:]
        //遍历
        for children in mirror.children {
            if let value = children.value as? CustomJSONMap {
                if let keyName = children.label {
                    //递归
                    keyValue[keyName] = value.jsonMap()
                }else{
                    throw JSONMapError.emptyKey
                }
            }else{
                throw JSONMapError.notConformProtocol
            }
        }
        return keyValue
    }
}
  • 发现改成throw抛出错误后,编译器提示有错,其原因是因为方法并没有声明成throws

2251862-00e071c673e02511.jpg

  • 所以还需要在方法的返回值箭头前增加throws(表示将方法中错误抛出),修改后的默认实现代码如下所示
//1、定义一个JSON解析协议
protocol CustomJSONMap {
    func jsonMap() throws-> Any
}
//2、提供一个默认实现
extension CustomJSONMap{
    func jsonMap() throws -> Any{
        let mirror = Mirror(reflecting: self)
        //递归终止条件
        guard !mirror.children.isEmpty else {
            return self
        }
        //字典,用于存储json数据
        var keyValue: [String: Any] = [:]
        //遍历
        for children in mirror.children {
            if let value = children.value as? CustomJSONMap {
                if let keyName = children.label {
                    //递归
                    keyValue[keyName] = value.jsonMap()
                }else{
                    throw JSONMapError.emptyKey
                }
            }else{
                throw JSONMapError.notConformProtocol
            }
        }
        return keyValue
    }
}
  • 由于我们在jsonMap方法中递归调用了自己,所以还需要在递归调用前增加 try 关键字
//2、提供一个默认实现
extension CustomJSONMap{
    func jsonMap() throws -> Any{
        let mirror = Mirror(reflecting: self)
        //递归终止条件
        guard !mirror.children.isEmpty else {
            return self
        }
        //字典,用于存储json数据
        var keyValue: [String: Any] = [:]
        //遍历
        for children in mirror.children {
            if let value = children.value as? CustomJSONMap {
                if let keyName = children.label {
                    //递归
                    keyValue[keyName] = try value.jsonMap()
                }else{
                    throw JSONMapError.emptyKey
                }
            }else{
                throw JSONMapError.notConformProtocol
            }
        }
        return keyValue
    }
}

<!--使用时需要加上try-->
var t = CJLTeacher()
print(try t.jsonMap())

到此,一个完整的错误表达方式就完成了