ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift #15 - 에러처리
    Swift의 온도 2021. 1. 26. 00:43

     

    1. 예외 상황

     

    - 예외 상황

    #예외가 발생할 수 있는 상황

     *파일 처리 중 디스크 에러

     *권한이 부족한 상황

     

    #에러 발생해도 크래쉬 되지 않도록

     

    - 에러 발생 API

    #예외가 발생할 수 있는 상황

    *throws로 선언
    *파일에 저장 API
     
    func write(toFile: String,
        atomically useAuxiliaryFile:Bool,
        encoding enc: String.Encoding) throws
    cs

     

    - throws 함수 호출하기

    #throws 함수 호출하기

    *try를 이용해서 호출
    *컴파일 에러 안 남
    *그러나 에러 발생 - 애플리케이션 크래쉬
     
    try str.write(toFile: filePath, atomically: true, encoding: .utf8)
    cs

     

    - 에러 다루기

    #에러 다루기

    *에러가 발생 -> 애플리케이션의 크래쉬 방지
    *do-catch 블로과 함께 사용
    *에러가 발생하면 catch 내 코드 실행
     
    do {
        try str.write(toFile: wrongFilePath,
            atomically: true, encoding: .utf8)
    }
    catch {
        print("에러 발생")
    }
    cs

     

    #발생한 에러 정보 얻기

    *catch에서 에러 바인딩
     
    do {
        try str.write(toFile: wrongFilePath, atomically: true,
    encondig: .utf8)
    }
    catch let error {
        print("에러 발생", error)
    }
    cs

     

    - 반환값과 에러

    #반환값이 있는 함수의 에러

    init(contentsOffile path: String)) throws{}
    func increasePositive(num : Int) throws -> int {}
     
    *try를 이용한 호출
     
    let str = try String(contentsOfFile: filePath)
    let num = try incresePositive(num: 99)
     
    *에러 다루기 : do-catch
     
    do {
        let str3 = try String(contentsOfFile: wrongFilePath)
    }
    catch let error {}
    cs

     

    #try? 로 호출하기

    *에러 발생 시 nil 반환
    *반환 타입은 옵셔널
     
    let str = tryString(contentsOfFile: wrongFilePath)
    cs

     

    #try! 로 호출하기

    *에러 발생 시 애플리케이션 크래쉬
    *반환 타입은 언래핑(non-optional)
     
    let str = tryString(contentsOfFile: wrongFilePath)
    cs

     

    2. 커스텀 에러 정의

     

    - 에러 정의

    #커스텀 에러 정의

     *Error 프로토콜

     *NSError 클래스(Foundation 프레임워크)

     

    #Error 프로토콜로 커스텀 에러 정의

     *Enum으로 정의

     *Struct/Class로 정의

     

    #Enum으로 에러 정의

    *Enum의 원소 타입을 Error으로
     
    enum CustomError : Error {
        case myFault
        case yourFault
    }
     
    *에러 발생시키기 : throw
     
    throw CustomError.myFault
    cs

     

    #구조체와 클래스로 에러 작성

    *Error 프로토콜 채택
     
    struct CustomErrorStruct : Error {
        var msg : String
    }
     
    class CustomErrorClass : Error {
    }
     
    *에러 발생 시키기
     
    let error = CustomErrorStruct(msg:"Oooops!")
    throw error
    cs

     

    - 에러 다루기

    #에러 구분하기

    *Enum으로 정의한 개별 에러 다루기
    *catch 에서 Enum에 에러 나열
    *swtich-case와 비슷한 방식
     
    do {
        throw CustomError.youtFault
    }
    catch CustomError.myFault {
        print("내탓")
    }
    catch CustomError.youtFault {
        print("남탓")
    }
     
    *struct/class로 정의한 에러
    *where를 이용한 타입 체크로 구별
     
    do {
        let error = CustomErrorStruct(msg:"Oooops!")
        throw error
    }
    catch let error where error is CustomErrorStruct {
        print("구조체로 작성한 에러 발생")
    }
    catch let error where error is CustomErrorClass {
        print("클래스로 작성한 에러 발생")
    }
    catch let error {
        print("그외 에러 발생", error)
    }
    cs

     

    3. 에러 발생 가능 API 작성

     

    - 에러가 발생할 수 있는 함수

    #에러 발생 가능한 함수 작성

    *0 보다 큰 수만 입력
    *그 외 입력값에는 에러
     
    func inputPositive(val : int) throws {
        guard val > 0 else {
            throw CustomError.yourFault
        }
        print("정상 수행")
    }
     
    *호출/에러 다루기
     
    do {
        try inputPositive(0)
    catch {
        print("에러 발생")
    }
    cs

     

    - 반환값이 잇는 함수와 에러

    #반환값이 있는 에러 발생 가능 함수

    *0보다 큰 수를 입력 가능, 1증가된 값 반환
    *그 외 입력에는 에러 발생
     
    func inputPositive(num : int) throws -> Int {
        guard num > 0 else {
            throw CustomError.yourFault
        }
        return num + 1
    }
    cs

     

    #반환값이 있는 에러 발생 함수 사용하기

    *호출, 에러 처리, 반환값 얻기
     
    do {
        let ret = try increasePositive(num: 1)
    }
    catch let error {
    }
     
    *try? 로 호출/에러 발생 - nil 반환
     
    let reslut = try? dangerousFunction()
     
    *try!로 호출/에러 발생 시 = 크래쉬
     
    let result = try! dangerousFunction()
    cs

     

     

    - 내부에서 에러 다루기

    #함수 내부에서 에러 다루기

    *함수 내부에 에러 발생 가능 함수 호출
    *do-catch로 함수 내부에서 에러 다루기
     
    func dolt() {
        do {
            try dangerousFunction()
        }
        catch let error {
            print("에러를 함수 내부에서 다루기", error)
        }
    }
     
    *호출
     
    dolt()
    cs

     

    - 발생한 에러를 전파하는 함수

    #내부에서 발생한 에러 전파

    *함수 내부에 do-catch 없음. throws 작성
     
    func dolt2() throws {
        //에러를 처리하지 않고 전파한다.
        try dangerousFunction()
    }
     
    *호출. throws 함수이므로 try, do-catch 사용
     
    do {
        try dolt2()
    }
    catch let error {
    }
    cs

     

    - 에러 발생 클로저

    #에러 발생 클로저를 사용하는 함수 정의

    *파라미터에서
     
    func dolt(_ arg : () throws -> () ) {
    }
     
    *반환 타입에서
     
    func dolt2() -> throws -> () {
        return dangerousFunction
    }
    cs

     

    #클로저에서만 발생한 에러 전파 : rethrow

    func dolt3(_ arg : () throws -> () ) rethrow {
        try arg()
    }
     
    *함수 사용하기, 클로저 파라미터로 입력
     
    do {
        try dolt3 {
            throw CustomError.myFault
        }
    }
    catch let error {
    }
    cs

     

    4. 클린업

     

    - 에러가 발생할 수 있는 함수

    #클린업(defer)

    *try-catch-finally 와 유사 그러나 다름
    *finally는 try-catch와 함께 작성
    *defer는 예외가 발생하는 곳에 작성
     
    func dangerousFunction() throw {
        defer {
            print("동작 마무리")
        }
        throw CustomErrorStruct(msg: "에러 발생!")
    }
    cs

    'Swift의 온도' 카테고리의 다른 글

    Swift #16 - Any와 타입 체크, 제네릭스  (0) 2021.01.27
    Swift #14 - 프로토콜, extension  (0) 2021.01.22
    Swift #13 - 클로저  (0) 2021.01.21
    Swift #12 - 구조체와 Enum  (0) 2021.01.20
    Swift #11 - 메모리 관리  (0) 2021.01.19

    댓글