Flutter Async dispose method

Chance·2024년 8월 14일
  
  Future<void> dispose() async {
    super.dispose(); /// 해당 코드를 하단으로 내리면 에러가 발생, 상단에 놓으면 정상
    Log(TAG, 'SettingScreen dispose call - 1');
    await something(true);
    Log(TAG, 'SettingScreen dispose call - 2');
  }

output :
SettingScreen dispose call - 1
something : true
SettingScreen dispose call - 2

super.dispose()는 State의 dispose() 메서드에서 동기적으로 호출되어야 합니다.

StatefulElement.unmount는 dispose() 메서드가 반환된 직후에 super.dispose()가 호출되었는지 확인합니다.

예를 들어, 비동기적으로 정의된 dispose() 메서드는 호출자에게 미래(Future)를 반환하고 지연 실행을 위한 작업을 예약합니다. 이 경우, 미래가 반환되면 StatefulElement.unmount는 계속 진행되어 검사를 수행하지만, super.dispose() 호출은 지연된 작업에서 발생할 것이기 때문에 검사가 실패합니다.

따라서 dispose() 메서드는 비동기 작업을 시작하기 전에 super.dispose()를 호출해야 합니다. 예를 들어, 다음과 같이 작성할 수 있습니다:

코드 복사
void dispose() {
  Log.d('stopping Player on dispose');
  super.dispose();
  _stop(supressState: true).then((_) => _player.release());
}

설명:

super.dispose()의 동기 호출 필요성:

dispose() 메서드는 위젯이 상태를 더 이상 필요로 하지 않을 때 호출됩니다. 이 메서드에서 super.dispose()를 동기적으로 호출해야 하는 이유는 StatefulElement.unmount가 dispose() 메서드가 반환된 후에 super.dispose()가 호출되었는지 검증하기 때문입니다. 즉, dispose()가 반환된 직후에 super.dispose()가 호출되어야 합니다.

비동기 dispose() 메서드 문제:

dispose() 메서드에서 비동기 작업을 시작하면, 이 메서드는 미래(Future)를 반환하게 됩니다. 이 미래가 반환되면 StatefulElement.unmount는 계속 진행하며, 이 시점에서 super.dispose()가 호출되지 않았다면 검사에서 실패할 수 있습니다. 이는 super.dispose()가 비동기 작업에서 지연되어 호출되기 때문입니다.

올바른 비동기 작업 처리 방법:

dispose() 메서드에서 비동기 작업을 시작하기 전에 먼저 super.dispose()를 호출해야 합니다. 이렇게 하면 super.dispose()가 동기적으로 호출된 후에 비동기 작업을 시작할 수 있습니다.
예를 들어, 위의 코드에서 dispose() 메서드는 먼저 super.dispose()를 호출하여 상태를 정리한 후, 비동기 작업 _stop()을 시작하고, 작업이 완료된 후 _player.release()를 호출합니다. 이 방식은 dispose() 메서드가 동기적으로 super.dispose()를 호출한 후에 비동기 작업을 수행하므로 StatefulElement.unmount의 검사를 통과할 수 있습니다.

출처 : https://github.com/flutter/flutter/issues/64935

0개의 댓글