말랑한 하루
[Flutter] AutoDispose? 본문
reference : https://riverpod.dev/ko/docs/concepts/modifiers/auto_dispose
우리가 Notifier를 구현하다 보면, 자연스레 NotifierProvider의 Instance가 Application에 남아있게 된다. 하지만 NotifierProvider를 사용하지 않는 경우에는 해당 Instance는 메모리 낭비이기 때문에 이를 해결하기 위한 autoDispose 옵션을 사용한다.
정형화하여 설명하자면, AutoDispose는 Provider Package의 확장된 클래스입니다. 공급자의 수명 주기를 자동으로 관리하여 공급자가 더 이상 필요하지 않을 때 폐기되도록 설계되었습니다. 이 기능은 메모리 누수를 방지하기 위해 삭제해야 하는 상태를 처리할 때 유용하게 사용됩니다. 자세한 이점은 다음과 같습니다.
🍒 auto dispode: 자동 삭제
AutoDisposeProvider를 사용하면, 연결된 위젯 트리가 더 이상 사용되지 않을 때 공급자가 자동으로 폐기됩니다.
🍒 성능 최적화
공급자를 자동으로 삭제하면 더 이상 필요하지 않은 리소스를 해제하여 Application의 성능을 최적화 할 수 있습니다.
🍒 Clean code
공급자를 수동으로 삭제해야 하는 필요성을 없애고, 코드 베이스를 더욱 깔끔하게 만들어 오류 발생 가능성을 줄여 코드를 단순화 합니다.
🐇 dispose?
그렇다면 dispose란 무엇일까요?
dispose는 Flutter에서 객체를 트리에서 영구적으로 제거하기 위해 호출하는 method를 담당하고 있다. State 개체가 다시 빌드 되지 않을 때 dispose method가 호출된다.
dispose를 호출한 후 State 객체는 UnMounted 상태가 되며, 이 시점에서 State를 변경하는 행위는 오류로 간주된다. 그래서 이 과정은 Flutter LifeCycle의 최종 단계이다. 삭제된 State 객체를 다시 마운트 할 방법은 없기 때문이다.
🐇 autoDispose?
autoDispose는 riverpod에서 더 이상 사용하지 않는 Provider의 상태를 destory, 소멸 하기 위해 Provider에 수식어를 붙여서 사용합니다. 예시는 다음과 같습니다.
final userProvider = StreamProvider.autoDispose<User>((ref) {});
이후에 userProvider가 더 이상 사용되지 않을 때 자동으로 해제 작업을 진행합니다.
🥕 autoDispose Detail
그렇다면 autoDispose가 무엇인지 더 자세히 알아보겠습니다. 이 칼럼에서는 autoDispose method에 대해 설명할 뿐 AutoDiposeNotifier 등의 Class에 대해선 설명하지 않습니다.
🍒 ref.keepAlive
Provider에 autoDispose 수식어를 붙이면 ref 객체에서 keepAlive method를 사용할 수 있습니다. 이 메소드를 사용하면, Provider가 참조되지 않게 되었을 때에도 상태를 유지하도록 riverpod에 전달합니다.
final myProvider = FutureProvider.autoDispose((ref) async {
final response =await httpClient.get(...);
ref.keepAlive();
return response;
});
위의 방식을 사용하면, 만약에 요청이 실패하고 사용자가 화면 상에서 떠나고 다시 들어온 경우 요청을 재 실행할 수 있도록 합니다. 그러나, 만약 요청이 성공적으로 처리된다면, 상태가 유지될 것입니다. 그리고 화면에 재 진입해도 새로운 요청을 위한 트리거링이 발생하지 않습니다.
🍒 HTTP requset cancle
FutureProvider와 ref.onDispose에 결합할 수 있습니다. Provider를 더 이상 사용하지 않을 때 쉽게 HTTP 요청을 취소할 수 있습니다. 이 과정의 목표는 다음과 같습니다.
- 사용자가 화면에 들어오면 HTTP 요청을 시작
- 만약, 요청이 완료되기 전에 사용자가 화면을 떠났다면 HTTP 요청을 중지
- 만약, 요청이 성공했다면 화면을 떠나거나 재 진입했을 때 새로운 요청을 시작하지 않음
그에 대한 예시 코드와 설명은 다음과 같습니다.
final myProvider = FutureProvider.autoDispose((ref) async {
// http 요청을 취소하기 위한 package:dio 객체
final cancelToken = CancelToken();
// 프로바이더가 해제(destroyed)될 때, http 요청을 취소합니다.
ref.onDispose(() => cancelToken.cancel());
// 데이터를 가져오고 취소하기 위한 `cancelToken`을 파라미터로 념겨줍니다.
final response = await dio.get('path', cancelToken: cancelToken);
// 만약 요청이 성곡적으로 완료되었다면, 현재 상태를 유지합니다.
ref.keepAlive();
return response;
});
🍒 Can`t be assigned to parameter on AlwaysAliveProviderBase
위 에러가 발생하면서 컴파일이 중지되는 오류는, 버그가 발생할 가능성이 높기 때문에 발생하는 오류입니다. 그에 대한 오류 코드와 정정 코드는 다음과 같습니다.
// error code example
final firstProvider = Provider.autoDispose((ref) => 0);
final secondProvider = Provider((ref) {
// 'AutoDisposeProvider<int>'인자 값을
// 'AlwaysAliveProviderBase<Object, Null>' 파라미터 타입으로 할당할 수 없습니다.
ref.watch(firstProvider);
});
// modify code example
final firstProvider = Provider.autoDispose((ref) => 0);
final secondProvider = Provider.autoDispose((ref) {
ref.watch(firstProvider);
});
여기까지 AutoDispose Class와 dispose의 의미, autoDispose method와 그 활용방법에 대해 알아보았습니다.
'개발 > Flutter' 카테고리의 다른 글
[Flutter] (Proejct) MapleApp: 2. GoRouter (0) | 2024.01.02 |
---|---|
[Flutter] (Project) MapleApp: 1. 프로젝트 시작 (0) | 2024.01.01 |
[Flutter] Dio 시작하기 (0) | 2023.12.30 |
[Flutter] (Error) requires SDK version >=3.2.3 <4.0.0, version solving failed. (0) | 2023.12.30 |
[Flutter] GoRouter 시작하기 (1) | 2023.12.29 |