Flutter

์ฝ”๋””๋„ค์ดํ„ฐ ํŒจํ„ด์„ ํ”Œ๋Ÿฌํ„ฐ์— ์ ์šฉํ•˜๋ฉฐ ์ƒ๊ธด _debugLocked ์—๋Ÿฌ

flutter developer 2025. 1. 14. 15:55

๐Ÿ“Œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€

Assertion failed: file:///Users/jayoengchoi/flutter/packages/flutter/lib/src/widgets/navigator.dart:5645:12
!_debugLocked is not true
See also: https://docs.flutter.dev/testing/errors

  • Presentation Layer๋ฅผ MVVM-C ํŒจํ„ด์œผ๋กœ ๋กœ๊ทธ์ธ ์œ ๋ฌด์—๋”ฐ๋ผ ์ฝ”๋””๋„ค์ดํ„ฐ๋กœ ๋„ค๋น„๊ฒŒ์ดํŒ…ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ์—ˆ๋‹ค.
  • Navigator.push() ํ˜ธ์ถœ ์‹œ ์•ฑ์ด ๊ฐ•์ œ ์ข…๋ฃŒ(Crash) ๋˜๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒํ–ˆ๋‹ค.

๐Ÿ”Ž ๋ฐœ์ƒ ์›์ธ ๋ถ„์„

1๏ธโƒฃ _debugLocked๋ž€?

Flutter์˜ Navigator๋Š” ์ค‘๋ณต ๋„ค๋น„๊ฒŒ์ด์…˜ ํ˜ธ์ถœ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด _debugLocked ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

  • Navigator.push() ๋˜๋Š” Navigator.pop()์ด ํ˜ธ์ถœ๋˜๋ฉด _debugLocked = true๊ฐ€ ๋˜์–ด ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ๋‹ค๋ฅธ ๋„ค๋น„๊ฒŒ์ด์…˜ ํ˜ธ์ถœ์„ ๋ง‰๋Š”๋‹ค.
  • _debugLocked == true ์ƒํƒœ์—์„œ ์ถ”๊ฐ€๋กœ push()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด Assertion ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๐Ÿ“Œ ์ฆ‰, ๋„ค๋น„๊ฒŒ์ด์…˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋๋‚˜๊ธฐ ์ „์— ์ƒˆ๋กœ์šด push()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•œ๋‹ค.

 

2๏ธโƒฃ  navigatorKey.currentState == null

 

์›๋ž˜ ์•ฑ์˜ ์‹œ์ž‘์ ์ธ ๋ฉ”์ธํŒŒ์ผ์˜ MaterialApp ์—์„œ navigatorKey๋ฅผ ๋„ฃ์–ด์ฃผ์–ด์•ผํ•œ๋‹ค. ํ•˜์ง€๋งŒ MVVM-C ํŒจํ„ด์„ ์œ„ํ•ด ํ™”๋ฉด์ „ํ™˜ ๊ด€๋ จ ์ฝ”๋“œ๋Š” ์ฝ”๋””๋„ค์ดํ„ฐ ๊ฐ์ฒด์— ์บก์Šํ™”ํ•ด ๋‘” ์ƒํƒœ์˜€๊ณ  navigatorKey ๊ฐ€ ๋Šฆ๊ฒŒ ํ˜ธ์ถœ๋จ์— ๋”ฐ๋ผ currentState == null ์ธ ์ƒํ™ฉ์—์„œ ์ฒซ ๋ทฐ์ „ํ™˜์ด ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.

 

3๏ธโƒฃ navigatorKey.currentState == null๊ณผ _debugLocked์˜ ๊ด€๊ณ„

 

๐Ÿšจ ์งˆ๋ฌธ: navigatorKey๊ฐ€ null์ด๋ฉด ์™œ _debugLocked ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ• ๊นŒ?

 

navigatorKey.currentState == null์ธ ์ƒํƒœ์—์„œ Navigator.push()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด Flutter๋Š” ์ƒˆ๋กœ์šด NavigatorState๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด build()๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•œ๋‹ค.

 

์ด ๊ณผ์ •์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ผ์ด ๋ฐœ์ƒํ•œ๋‹ค:

  1. Navigator.push()๊ฐ€ ์‹คํ–‰๋จ
    • ์ด๋•Œ navigatorKey.currentState == null์ด๋ฉด NavigatorState๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด build()๊ฐ€ ๋‹ค์‹œ ํ˜ธ์ถœ๋จ.
  2. Flutter๊ฐ€ ์œ„์ ฏ์„ ๋ฆฌ๋นŒ๋“œํ•˜๋Š” ๊ณผ์ •์—์„œ _debugLocked๊ฐ€ ํ™œ์„ฑํ™”๋จ
    • Navigator๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์‹œ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด _debugLocked = true๋กœ ์„ค์ •ํ•จ.
    • ํ•˜์ง€๋งŒ ์ด ๊ณผ์ •์—์„œ ๋‹ค์‹œ push()๊ฐ€ ์‹คํ–‰๋  ๊ฒฝ์šฐ _debugLocked๊ฐ€ ์ด๋ฏธ true ์ƒํƒœ์ด๋ฏ€๋กœ Assertion ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ.
  3. ์ฆ‰, navigatorKey.currentState == null ์ƒํƒœ์—์„œ push()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด Navigator๊ฐ€ ์™„์ „ํžˆ ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ๋™์ž‘ํ•˜๊ฒŒ ๋˜๊ณ , ์ด๋กœ ์ธํ•ด _debugLocked๊ฐ€ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์ƒํƒœ์—์„œ ์œ ์ง€๋จ.

๐Ÿ“Œ ์ •๋ฆฌํ•˜๋ฉด, navigatorKey.currentState == null ์ƒํƒœ์—์„œ ๋„ค๋น„๊ฒŒ์ด์…˜์„ ํ˜ธ์ถœํ•˜๋ฉด Flutter๊ฐ€ ๋„ค๋น„๊ฒŒ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ณผ์ •์—์„œ _debugLocked๊ฐ€ ์˜ˆ์ƒ๋ณด๋‹ค ์˜ค๋ž˜ ์œ ์ง€๋˜๋ฉฐ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด๋‹ค.


๐Ÿ’ก ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

WidgetsBinding.instance.addPostFrameCallback() ํ™œ์šฉ

WidgetsBinding.instance.addPostFrameCallback()  ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด _debugLocked = false ๊ฐ€ ๋˜์–ด์•ผ ๋‹ค์Œ ์•ก์…˜์ด ๋“ค์–ด๊ฐ„๋‹ค. ์ฆ‰, ํ˜„์žฌ UI ์—…๋ฐ์ดํŠธ ๋ฐ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋ฐ ์…‹ํŒ…์ด ์™„๋ฃŒ๋œ ์ดํ›„์— ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ด์ „ ์ž‘์—…(navigator ๋นŒ๋“œ)๊ฐ€ ์™„๋ฃŒ๋˜์–ด navigatorKey.currentState = null ์ด ์•„๋‹Œ ์ƒํƒœ์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ Navigator.push()๊ฐ€ ์‹คํ–‰๋œ๋‹ค.