// 错误和异常处理
// 一些在开发阶段的错误,比如 向一个无法响应某个消息的 NSObject对象发送了消息,会得到 NSInvalidArgumentException的异常,或者数组越界会得到 NSRangeException。
// 在 OC 中的 NSError 往往是app开发中那些'合理的', 比如, 网络回调用户密码不匹配,读取已经被移除的文件生成 NSData 时
if let url = Bundle.main.url(forResource: "main.json", withExtension: nil) {
let data = NSData(contentsOf: url)
let docDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let jsonPath = docDir.appending("/main.json")
_ = data?.write(toFile: jsonPath, atomically: true)
}
// 在使用这个方法的时候,要么调用这个方法的时候,前面加入 try?, 要么 使用 do catch
// open func write(to url: URL, options writeOptionsMask: NSData.WritingOptions = []) throws
let data = NSData()
do {
try data.write(toFile: "hello", options: [])
}
catch let error as NSError {
print("Error:\(error.domain)")
}
// 这类异常是可以捕获,并判断的
enum LoginError: Error {
case UserNotFound, UserPasswordNotMatch
}
// 账号密码存储的字典
let users = [String: String]()
func login(user: String, password: String) throws {
if !users.keys.contains(user) {
throw LoginError.UserNotFound
}
if users[user] != password {
throw LoginError.UserPasswordNotMatch
}
print("Login successfully")}
// 这样 ErrorType 可以非常明确的指出问题所在。
do {
try login(user: "abc", password: "123")
}
catch LoginError.UserNotFound {
print("UserNotFound")
}
catch LoginError.UserPasswordNotMatch {
print("UserPasswordNotMatch")
}
// 这种写法和 JAVA C# 不同, 他们是 try catch// 和枚举进行关联enum Result { case Success(String) // 可是使用泛型 Successcase Error(NSError)
}
func doSomethinagParam(param: AnyObject) -> Result {
let success : Bool
// ...
success = true
if success {
return Result.Success("成功完成")
} else {
let error = NSError(domain: "eooroDomain", code: 1, userInfo: nil)
return Result.Error(error)
}
}
// 使用的时候
let param = "dddd"
let result = doSomethinagParam(param: param as AnyObject)
switch result {
case let .Success(ok):
let serverResponse = ok
case let .Error(error):
let serverResponse = error.description
}
// 使用 try? func(throws) 表明是忽视了 error 并且在 error产生的时候得到一个 nil 例如
enum E: Error {
case Negative
}
func methodThrowsWhenPassingNegative(number: Int) throws -> Int{
if number < 0 {
throw E.Negative
}
return number
}
if let num7 = try? methodThrowsWhenPassingNegative(number: 100) {
print(num7) // 100
print(type(of: num7)) // Int
}
// 在一个 throws 的方法里,不要返回一个 optional 值