美文网首页Swift
Swift--错误处理

Swift--错误处理

作者: 优雅的步伐 | 来源:发表于2020-07-02 23:49 被阅读0次

    do-try-catch错误处理模式

    Swift2.x抛弃了cocoa的错误处理模式,使用了do-try-catch错误处理模式

    cocoa的错误处理模式

    let contents = NSString(contentsOfFile: filePath, encoding: NSUTF8StringEncoding, error: nil)
    
    或者
    var err: NSError?
    
    let contents = NSString(contentsOfFile: filePath, encoding: NSUTF8StringEncoding, error: err)
    

    由于Objective-C和Swift1.x没有强制处理机制,因此一旦真的发生错误,程序就会崩溃

    do-try-catch错误模式

    do {
        let str = try NSString(contentsOfFile: filePath, encoding: NSUTF8StringEncoding)
    
    } catch let err as NSError {
        print(err.description)
    }
    

    : do-tyr-catch这种错误模式与Java中异常处理机制非常类似,本意就是尝试( try )做一件事情,如果失败则捕获( catch )处理

    捕获错误

    完整的do-try-catch错误处理模式语法如下:
    do {
    try 语句
    成功处理语句组
    } catch 匹配错误 {
    错误处理语句组
    }

    错误类型

    在Swift中错误类型必须遵从Error Type协议,其次是考虑错误类型的匹配,它应该设计为枚举类型,因为枚举类型非常适合将一组相关值关联起来。

    enum DAOError: Error {
        case NOData
        case PrimaryKeyNull
    }
    
    do {
        //try 访问数据表函数或方法
    } catch DAOError.NOData {
        print("没有数据。")
    }catch DAOError.PrimaryKeyNull {
        print("主键为空。")
    }
    
    在函数或方法中抛出错误
    • 在函数或方法中通过throw语句人为地抛出错误
    • 在函数或方法中调用其他可以抛出错误的函数或方法,但是没有捕获处理,会导致错误被传播出来

    //删除Note 方法
    func remove(model: Note) throws {
        guard let date = model.data else {
            //抛出“主键为空”错误
            throw DAOError.PrimaryKeyNull
        }
    
        //比较日期主键是否相等
        for (index, note) in listData.enumerate() where note.date == date     {
            listData.removeIndex(index)
        }
    }
    
    //查询所有数据方法
    func findAll() throws -> [Note] {
        guard listData.count > 0 else {
            //抛出“没有数据”错误
            throw DAOError.NoData
        }
      return listData
    }
    
    func printNotes() throws {
        let datas = try findAll()
        for note in datas {
            print("data: \(note.date!) - content:\(note.content!)")
        }
    }
    
    try printNotes()
    

    1、remove方法我们声明为有可能发生错误,加了个throws, 如果 let date = model.date 成立的话,走for语句,否则抛出异常“ throw DAOError.PrimaryKeyNull”,跳出程序代码。
    2、findAll方法我们声明为有可能发生错误,加了个throws, 有返回值[Note],如果“listData.count > 0” 成立,返回listData,否则抛出异常。
    3、printNotes方法我们声明为有可能发生错误,加了个throws。
    方法内部调用findAll方法,即在printNotes方法中调用了可以抛出错误的findAll方法,所以前面要加try,但却没有用catch捕获处理这个错误,一旦发生错误,捕获不到错误,方法不会继续往下走,跳出方法,往下传播,传播它的上层调用者,把错误给上层调用者,上层调用者还是处理不了的话,在往下传,最后传到运行环境,然后崩溃。

    4、调用“try printNotes()” ,会调用printNotes方法, 调用printNotes方法又会调用findAll方法,如果findAll方法中有错误发生的情况下,错误传递给findAll方法,findAll方法又会传递给printNotes方法,然后再传递给“try printNotes”。如果“try printNotes”也不捕获的话就会传递给运行环境,运行环境遇到错误后就会崩掉。

    对错误进行捕获和处理,并不是所有的函数和方法都有这个必要性,有的是没有这个必要性的,所以只能往上传播给它的调用者。有的函数和方法是需要捕获并处理的

    比如一些权限的问题,有人有必要有能力来处理这个错误,把错误抛给他,他来处理。比如有些错误是给用户看的,有些是给管理员看的,如果是给用户看的错误要抛给表示层(view, viewController),如果是给系统管理员看的,直接打印日志,存到数据库里,或发个邮件就可以了。

    声明抛出错误

    能放到try后面调用的函数或方法都是有要求的,它们是有可能抛出错误,但你要在这些函数或方法声明的参数后面加上throws关键字,表示这个函数或方法可以抛出错误。

    示例:

    //删除Note记录的方法
    func remove(model: Note) throws {
            ...
    }
    
    //查询所有记录数据的方法
    func findAll() throws -> [Note] {
            ...
    }
    
    try? 和 try!的使用区别

    1、使用try

    try?会将错误转换为可选值,当调用try? + 函数或方法语句时,如果函数或方法抛出错误,程序不会崩溃,而是返回一个nil; 如果没有抛出错误,则返回可选值。

    func findAll() throws -> [Note] {
        guard listData.count > 0 else {
            //抛出“没有数据”错误
            throw DAOError.NoData
        }
        return listData
    }
    
     let datas = try? findAll()
    
      print(datas)
    

    2、使用try!

    使用try!可以打破错误传播链条。错误抛出后被传播者捕获,这样就形成了一个传播链条,有时我们确实不想让错误传播下去,这时便可以使用try!语句。

    //查询所有数据方法
    func findAll() throws -> [Note] {
        guard listData.count > 0 else {
            //抛出“没有数据”错误
            throw DAOError.NoData
        }
        return listData
    }
    
    func printNotes() {
        let datas = try! findAll()
        for note in datas {
            print("data: \(note.date!) - content:\(note.content!)")
        }
    }
    
    printNotes()

    相关文章

      网友评论

        本文标题:Swift--错误处理

        本文链接:https://www.haomeiwen.com/subject/mxehqktx.html