지난 글에 에러가 발생했을 때 알아본 것 처럼 required init이란 스토리보드나 xib파일로 뷰를 그렸을때 호출되는 이니셜라이즈로, 코드로 UI를 그렸을때 이 이니셜라이즈가 호출되면 즉시 종료하겠다는 의미로 fatalError를 사용했다.
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
💡 fatalError란?
fatalError 메소드를 자세히 보면 Never를 반환한다. 이 의미는 호출이 되면 더 이상 앱이 진행되지 않고 바로 종료된다. 따라서 앱이 종료되야 할 만큼 치명적인 에러가 발생할 때나 메소드에서 리턴할 것이 없을 때 사용된다.
func fatalError(_ message: @autoclosure () -> String = String(), file: StaticString = #file, line: UInt = #line) -> Never
다른 예시를 보면 테이블뷰의 셀을 그릴 때도 사용된다.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? TableViewCell else {
fatalError("The dequeued cell is not an instance of TableViewCell.")
}
return cell
}
재사용 큐에서 셀을 가져와서 TableViewCell 클래스의 인스턴스로 다운캐스팅해서 사용하는 코드이다. 다운캐스팅에 실패하면, 즉 as?가 nil을 반환하면 guard 안의 코드가 실행되는데 만약 다운캐스팅이 실패한다면 이는 에러가 발생한 것이므로 빈 셀을 반환하려고 시도하는게 아니라 개발자에게 의도치 않은 상황임을 알리고 앱을 중지시키는 것이다.
이렇게하면 코드는 셀을 안전하게 가져오고 만약에 셀의 타입이 fatal error인 경우 프로그램을 중지시켜 예상치 못한 상황에 대해 빠르게 대응할 수 있게 된다.
(적재적소에 사용하는 것이 중요하겠군..)