스위프트 공부를 하던 중 마주하게 된 첫 번째 에러가 발생했다.
우선 중단점을 지정해서 디버깅을 통해 어떤 에러인지 알아 봤다.
Thread 1: Fatal error : Unexpectedly found nil while unwrapping an Optional value
이후에 계속 코드 실행F6을 눌렀더니
Thread 1: EXC_BREAKPOINT (code=1, subcode=0x18f494588) 이런 에러로 바뀌었다.
(Thread가 왜이렇게 많지.. 선언 다 안해줬는데;;)
Thread 1에서 발생한 에러이다.
//위의 코드 상황을 말하자면 디폴트 VC(ViewController)를 삭제하고, TableViewController 를 생성, initial View Controller로 지정한 상태이다.
맨 처음에 list :( 특정 클래스의 배열 ) 의 특정 원소가 nil값이라고 생각했었는데 디버깅을 통해 살펴보니 값이 정상적으로 대입 되었다.
그렇다면 강제 옵셔널 해제 연산자를 사용하지 않고,
그 아래 코드에
cell!.textLabel?.text = row.title으로 아래 코드에 옵셔널 강제해제 연산 이후 옵셔널 체인으로 실행해도 이 코드가 문제가 아니라 여전히 위 코드에서 같은 에러 문장이 발생했다.
(구글링도 해보고)
(1시간 동안 해결 못하는 중..)
그러고 난 후 그냥 함수 정의를 봤는데 delegate로 연결된 셀을 사용한다는 주석만 있었다.
아래의 코드 문제도 아니고,120 번 줄에서 왜 에러가 발생했을까? 왜 예상치 못한 nil값이?
우선 tableView에 정의된 dequqReusableCell(withIdentifier:)메서드를 살펴봤다.
반환값은 UITableViewCell 옵셔널 타입이다. 인자값으로 입력받은 아이디를 이용해 스토리보드에 정의된 프로토타입 셀을 찾고, 인스턴스로 생성해서 제공한다.
반환값이다. 인자값으로 받은것과 object를 UITableViewCell로 반환한다.
또는 재사용 큐에 존재하지 않으면!! nil을 반환한다.
reusable-cell queue(재사용 큐)는 연관된 identifier에 맞는 object(인스턴스)가 있다면 그걸 꺼내서 쓰고, 그 인스턴스가 없다면 새로 생성해서 제공하는 방식이다.
이 문장을 확실하게 기억한다.
그래서 더욱 의문이었다... 잘 했는데 왜 에러가 나지?
고민만하고 아무것도 하지 않아서
여전히
cell의 값은 여전히 00000000000000이다.
120라인의 dequeueReusableCell메서드의 인자값인 "ListCell"에 대해서 생각을 해봤다.
이건 뭐지? 인스턴스가 없다면 새로 생성해서 제공 한다는데 왜 난 생성이 안되는거지?
ListCell인스턴스로 생성하는게 아닌가?
어?... ListCell을 내가 이전에 사용한 적이 있나? identifier 식별자? 뭐랑 연결되있지? (난 ListCell을 이전에 사용한 적이 없었다..)
?!!!! dequeueReusableCell은 UITableViewCell을 반환한다는데 TableViewCell?
그 순간 TableViewController는 TableView와 TableCell등 계층 구조?로 이루어진다는 것이 떠올랐다.
( Cell을 만약 재사용큐에서 생성하지 않는다면. 내가 잘못한 것인가? 내가 ListCell이라는 테이블 셀의 명칭을 정해야 인자값으로 주어진 String을 찾는 것인가? )
바로 연관된 인터페이스 빌더 안 테이블 뷰의 identifier를 확인했더니
어라 identifier가 비어있었다.
tableController의 특정 table cell 조차 식별하지 못해서 nil을 반환했던 것이었다.
정말로 메서드의 반환값 표기와 같이 재사용큐에 식별자가 없다면 nil을 반환하는 문장이 사실이었던 것이다.
(내 실수였던 것을 인정한다)(쭈글..)
포기하려했지만 30분만더..라는 생각과 함께 결국 오류를 찾게 된 것 같다..
딱 한 개의 오류로 인해
디버깅의 사용,
API문서의 설명은 대단하다는 것을 알게 됬다.