티스토리 뷰
becomeFirstResponder의 시점에 따라 deinit이 되지 않아 메모리 릭이 생기는 문제를 겪었다.
// viewWillAppear에서 becomeFirstResponder를 하면
// 뷰컨이 deinit될 때 TextField가 같이 deinit 되지 않음.
// viewWillDisappear에서 명시적으로 resign을 해줘도 안됨.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
couponCodeTextField.becomeFirstResponder()
}
// 굳이 명시적으로 resign 안해줘도 잘 deinit 됨
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
couponCodeTextField.becomeFirstResponder()
}
도대체 머가 문제지;;;;;;
일단 becomeFirstResponder를 언제 호출하느냐의 문제가 아니었음.
아 그리고 becomeFirstResponder는 viewWillAppear에서 해주면 안 됨!
becomeFirstResponder의 공식문서 설명 →
활성화된 뷰 계층에 속하지 않은(뷰 계층에 올라가지 않은) 뷰에서 이 메소드를 절대 부르지 마라!
그런데 viewWillAppear 는 ?
대충 "이 메소드는 뷰컨의 뷰가 뷰 계층에 막 추가되기 전에! 불린다 그니깐 이런저런 거~ 하면 된다"라는 뜻
즉 viewWillAppear가 불리는 시점은 뷰컨이 뷰 계층에 올라가기 전! 이기 때문에 becomeFirstResponder는 viewWillAppear에서 하면 안 됨!
여기서 하면 뷰컨이 deinit 될 때 같이 안됨..
추가적인 문제는,,
viewDidAppear에서 했는데도 메모리 해제가 안된다?? 이때의 문제는,,
viewDidLoad에서 setUp() 이런 식으로 전체적인 뷰 레이아웃을 잡거나 뷰를 초기화하거나 할 때 textField.text = "TEXT"
이렇게 textField의 초기 text값을 설정해두면, (보통 이렇게 값을 넣어둘 일이 없지만 테스트용으로 넣어뒀다가;;)
즉 textField에 becomeFirstResponder
를 호출하기 전에 text 값을 임의로 넣는다면 이것 때문에도 메모리 해제가 안될 수 있음.
중간 정리를 하자면 becomeFirstResponder
는 뷰 계층에 올라간 후에! 호출해야 함.
그리고 text를 흔히 말하는 programmatical 방법으로 임의로 넣어야 한다면 becomeFirstResponder
가 호출된 후에! 해야 함.
뷰컨이 해제된 후 메모리에 남아있는 TextField를 메모리 그래프로 본다면 이렇게 보임..
저 진한 선이 strong 참조를 나타내는데 UIKBAutofillController에 연결된 것을 알 수 있음.
구글링,, ios kbautofillcontroller
정확히는 알 수 없지만 대충 키보드의 자동완성 기능이랑 나의 TextField랑 눈 맞아서 서로를 안 놔주게 된 상황인 거 같으다..
그래서 위 링크에 나와있는 것처럼
textField.autocorrectionType = .no
textField에 이러한 속성을 추가해주면 viewWillAppear에서 하든(하면 안 되지만!!!), viewDidAppear에서 하든 메모리 해제가 아주 잘 된다...
근데 이렇게 하는 것은 결국엔 textField에 autocorrection을 지원하지 않겠다는 것이니 상황에 맞게 주의해서 사용해야겠다.
그리구 이때 OneTime Code(textContentType = .oneTimeCode
) 자동 완성도 안될지 테스트해봐야 할 것 같다.
❓추가적인 의문,,,
viewWillAppear에서 textField를 becomeFirstResponder 할 때랑 viewDidAppear에서 할때랑 눈으로 보이는 애니메이션 반응속도가 꽤 차이가 나는데,,,
이전에 사용해봤던 몇몇 앱에서 화면 전환하자마자 키보드가 올라왔던 경우를 생각해봤을 때 viewWillAppear에서 becomeFirstResponder를 하는 것 같은 반응속도였던 것 같은데,, 그런 데서는 어떤 식으로 대응을 했을지 궁금하다
'iOS' 카테고리의 다른 글
[번역] WatchKit (0) | 2022.01.20 |
---|---|
iOS status bar style 변경하기 (1) | 2021.11.18 |
Bastard Injection (0) | 2021.08.17 |
iOS App Life Cycle (2) | 2021.07.11 |
swift static, class, final class (0) | 2020.08.02 |
- Total
- Today
- Yesterday
- statusBarStyle
- 클론코딩
- Xcode
- split view controller
- 읏샷샤 화이팅 앗샷샤 화이팅
- iPad
- 냉철
- strings.xml
- spm
- ios
- Android
- watchKit
- 스토아학파
- 프론트엔드 공부
- watchOS
- watchOS life cycle
- opentutorial
- Localizable
- bitbucket
- iOS App Life Cycle
- 에피쿠로스
- SplitViewController
- lldb
- StatusBar
- 생활코딩
- private repository
- iPadOS
- 에피큐어
- 철학의 역사
- UISplitViewController
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |