플러터에서 가끔 "Unhandled Exception: setState() called after dispose()"라는 오류 메시지를 자주 만난다. 이 오류 메시지는 위젯 트리에 더 이상 마운트되지 않은 State object에서 setState() 메서드를 호출하는 데 문제가 있음을 알려준다. 이 문제는 타이머 또는 애니메이션 콜백에서 setState()를 호출할 때 발생할 수 있습니다.
dispose() 메서드는 상태 stateful widget이 위젯 트리에서 제거될 때 호출되는 수명 주기 메서드입니다. 이 메서드는 위젯의 수명 주기 동안 생성된 리소스나 리스너를 정리할 수 있는 기회를 제공합니다.
위젯이 폐기되면 프레임워크에서 dispose() 메서드가 자동으로 호출됩니다. stateful widget의 State class 에서 이 메서드를 재정의하여 필요한 정리 작업을 수행할 수 있습니다.
다음은 dispose() 메서드를 구현하는 방법의 예시입니다:
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
// Initialize resources or listeners
@override
void dispose() {
// Clean up resources or listeners
// Cancel timers, stop animations, close streams, etc.
super.dispose();
}
@override
Widget build(BuildContext context) {
// Widget build code
}
}
dispose() 메서드에서는 타이머 취소, 애니메이션 중지, 스트림 닫기, 이벤트 리스너 구독 취소, initState() 또는 위젯의 수명 주기 동안 할당된 기타 리소스 해제와 같은 정리 작업을 수행해야 합니다.
dispose() 메서드의 마지막에 super.dispose()를 호출하여 베이스 클래스의 dispose() 메서드도 호출되도록 하는 것이 중요합니다.
dispose() 메서드를 올바르게 구현하면 메모리 누수를 방지하고 이전 질문에서 발생한 것과 같은 오류를 방지할 수 있습니다.
만약 이 오류를 해결하지 않으면 여러 가지 문제가 발생할 수 있습니다:
앱 불안정: 이 오류는 위젯 트리에 더 이상 존재하지 않는 위젯에서 setState()를 호출하는 데 문제가 있음을 나타냅니다. 이 문제를 해결하지 않으면 앱에서 예측할 수 없는 동작과 불안정성이 발생할 수 있습니다. 이로 인해 충돌이나 예기치 않은 UI 결함이 발생하여 앱을 사용할 수 없게 되거나 사용자 경험에 부정적인 영향을 미칠 수 있습니다.
메모리 누수: 위젯이 트리에서 제거된 후에 setState()를 호출하면 메모리 누수가 발생할 수 있다는 오류 메시지가 표시됩니다. 메모리 누수는 객체가 제대로 폐기되지 않을 때 발생하며, 시간이 지남에 따라 메모리 소비가 증가합니다. dispose() 중에 State 객체에 대한 참조가 끊어지지 않으면 메모리 누수가 발생하여 앱의 전반적인 성능에 영향을 미칠 수 있습니다.
성능 저하: 오류를 해결하지 않으면 성능이 저하될 수 있습니다. 특히 트리에 더 이상 존재하지 않는 위젯에서 불필요하게 setState()를 호출하면 UI가 불필요하게 다시 렌더링될 수 있습니다. 이로 인해 CPU 및 메모리 사용량이 증가하여 앱이 느려지고 응답하지 않을 수 있습니다.
디버깅이 어렵습니다: 오류를 무시하면 디버깅을 통해 문제의 근본 원인을 파악하기가 더 어려워질 수 있습니다. 오류가 더 큰 코드베이스 또는 더 복잡한 시나리오에서 발생하는 경우 문제를 소스로 역추적하기가 어려울 수 있습니다. 이로 인해 디버깅 작업이 길어지고 좌절감을 느낄 수 있습니다.
앱의 안정성, 성능 및 유지 관리 가능성을 보장하려면 이 오류를 해결하고 오류 메시지에 제공된 제안된 해결 방법을 따르는 것이 중요합니다. 타이머를 적절히 취소하고, 애니메이션을 중지하고, 위젯의 마운트 상태를 확인하고, dispose() 중에 참조를 끊으면 이러한 문제를 방지하고 앱의 올바른 동작을 보장할 수 있습니다.
그래서 앱 라이프 사이클에서 위젯을 폐기할 때 리소스와 리스너를 적절히 정리하는 것을 꼭 기억해야 합니다.