[Swift] 오류 처리

승아·2021년 9월 1일
0

부스트코스-iOS 프로그래밍을 위한 스위프트 기초

1. 오류 표현

  • Error 프로토콜과 (주로) 열거형을 통해서 오류를 표현한다.
enum LocationManagerError: Error {
  case authorizationDenied
  case coordinateError
}

2. 함수에서 발생한 오류 던지기

  • 오류 발생의 여지가 있는 메서드는 throws를 사용하여 오류를 내포하는 함수임을 표시합니다.
func requestLocation(completion: @escaping (_ coordinate: CLLocationCoordinate2D) -> ()) throws {
  locationManager.delegate = self
  guard CLLocationManager.locationServicesEnabled() else {
    throw LocationManagerError.authorizationDenied
  }
  locationManager.requestWhenInUseAuthorization()
  locationManager.requestLocation()
  locationManager.desiredAccuracy = kCLLocationAccuracyBest
  guard let coordinate = locationManager.location?.coordinate else {
    throw LocationManagerError.coordinateError
  }
  completion(coordinate)
}

3. 오류 처리

  • 오류가 던져지는 것에 대비하여 던져진 오류를 처리하기 위한 코드를 작성해야합니다.

do-catch

  do {
    try locationManger.requestLocation(){ coordinate in
      currentLocationViewModel.convertToAddress(latitude: coordinate.latitude, longtitude: coordinate.longitude, completion: {
        let locationName = $0
        fineDustViewModel.loadFineDust(latitude: coordinate.latitude, longtitude: coordinate.longitude, completion: {
          let entry = simpleEntry(currentDate: currentDate,
                                  locationName: locationName,
                                  fineDust:  $0.fineDust,
                                  ultraFineDust: $0.ultraFineDust,
                                  configuration: configuration)
          let refreshDate = Calendar.current.date(byAdding: .minute, value: 30, to: currentDate)!
          let timeline = Timeline(entries: [entry], policy: .after(refreshDate))
          completion(timeline)
        })
      })
    }
  } catch {
    let entry = simpleEntry(currentDate: currentDate,
                            locationName: "오류",
                            fineDust: fineDustViewModel.fineDust("-"),
                            ultraFineDust: fineDustViewModel.ultraFineDust("-"),
                            configuration: configuration)
    let refreshDate = Calendar.current.date(byAdding: .second, value: 10, to: currentDate)!
    let timeline = Timeline(entries: [entry], policy: .after(refreshDate))
    completion(timeline)
  }
}

try?

  • 별도의 오류처리 결과를 통보받지 않고 오류가 발생했으면 결과값을 nil로 돌려받을 수 있습니다.
  • 정상동작 후에는 옵셔널 타입으로 정상 반환값을 돌려 받습니다.

try!

  • 오류가 발생하지 않을 것이라는 강력한 확신을 가질 때 try!를 사용하면 정상동작 후에 바로 결과값을 돌려받습니다.
  • 오류가 발생하면 런타임 오류가 발생하여 애플리케이션 동작이 중지됩니다.

Swift 3.0 의 throws, rethrows 에 대하여...

rethrows

  • 파라미터로 throwing 함수를 받을 때 throwing 함수를 받은 함수에서 오류 처리를 하지 않고 그 전에 받은 함수에서 오류 처리를 하는 것.
  • 위와 같은 상황에서 rethrows를 쓰지 않고 throws를 써도 문제는 없지만 에러를 함수로부터 받아서 다시 throwing하는지 아니면 자신이 에러를 thrwoing하는지 추측하기 위해서 구분해서 명시하는 편이 좋다.

defer 구문 알아보기

defer

현재 코드 블럭을 나가기 전에 꼭 실행되어야 하는 코드를 작성하여 코드가 블록을 어떻게 빠져나가던 꼭 마무리 해야 하는 작업을 수행하도록 하는 것을 말한다.

func test() {
    defer {
        print("실행 2")
    }

    print("실행 1")
}

// 실행 1
// 실행 2

0개의 댓글