View

300x250

최근에 해결하는데에 꼬박 4일이 걸린 문제가 있었다 ㅜㅜㅜㅜㅜ

뷰에서 작은 컴포넌트 위젯에서 GestureDetector를 통해 PanGesture를 인식하고, 터치 좌표값을 받아다가 뷰에게 전달하고, 뷰에서 이를 받아다가 setState로 값을 수정하면 다른 위젯에서 이 값으로 UI를 그리는 로직을 작성하고 있었다. 대충 그림으로 그리면 아래와 같다.

Untitled.png

이를 위해서 대략적으로 아래 플로우로 실행을 제어하려고 했다.

  1. View에서 GestureDetector가 달린 위젯에 콜백함수를 전달
  2. onPanUpdate 시 콜백함수 호출
  3. 콜백함수에서 setState 실행
  4. 뷰 다시 그리기
  5. position UI 반영

그런데 왠걸? onPanUpdate 함수가 1-2번 호출되고나면 콜백함수가 더 이상 실행되지 않는 문제가 있었다. print를 찍어봐도 한 프레임만 호출되고, 바로 GestureDetector 자체가 먹통이 되어버렸다.

결론적으로 말하자면 내가 GestureDetector가 달린 위젯을 Column 위젯에 넣었는데, 키 값을 잘못 할당해준게 문제였다. 이걸 깨닫기까지 4일이나 걸렸고, 다시 생각해도 눈물이 줄줄 나온다 😢😢

처음에는 문제가 콜백함수의 정의 위치라고 생각했다. 애초에 매 프레임 호출되는 함수 내에서 setState를 호출하면 갑자기 반응이 없어지고 매 프레임 찍혀야 할 print도 출력되지 않아서 앱이 멈춰버린다고 생각했다. 지피티한테 “setState를 호출하니 앱이 멈춰버리는 현상”을 물어봤을 때에는 build context를 잘못 지정해줘서 setState가 잘 실행되지 않은 것 같다고 답변하기에 이에 대해 조치를 취해주려 했다. 그러나 실패! 아무리 context를 전달해서 함수를 실행하거나 조정하려 해도 문제가 해결되지 않았었다.

그 다음에 생각했던 문제는, setState()를 호출하면서 하위 뷰를 새로 그리는데, 이 시점에 GestureDetector 위젯도 새로 그려져서 초기화되는 것이였다. 합리적 의심… 이였지만, 새로운 뷰를 간단하게 짜서 재현했을 때 문제없이 동작했다. 애초에 매 프레임 실행되는 onPanUpdate 함수에 setState를 넣는 코드들도 자연스럽고 예제도 굉장히 많았다.

그러다가, GestureDetector 위젯의 initState에 print 문을 찍어봤는데, onPanUpdate가 한 프레임 호출되고 나서 바로 initState가 호출되는 것을 확인했다.

아! 뭔가 문제가 있어서 하위 뷰가 확실히 새로 빌드가 되고 있고, 이것 때문에 터치하자마자 위젯이 새로 만들어지면서 문제가 발생하는구나! 를 알았다. 그러나, 이때까지만 해도 setState의 호출이 문제라고 생각하고 있었다.

그렇게 setState와 build context와 기타 여러가지로 재현하면 잘 되는데 실제상황에서는 안되는 기가막히는 문제로 3일이 넘게 쌩고생을 하다가 문제의 해결방법을 찾았다.

내가 위젯의 key에 UniqueKey를 넣어놨었는데, 새로 위젯을 빌드할 때 마다 새로운 UniqueKey를 넣어주면서 문제가 발생하는 것이였다….!!!! 요녀석을 일반 Key로 넣어줬더니 문제가 해결되었다. 하위뷰가 원치않게 재빌드된다면 key를 꼮꼮 확인하자.

4일동안 찾던 실마리가 단 한 줄의 코드 변경이였다. ㅋㅋㅋ

Untitled.png

320x100
Share Link
reply
반응형
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31