[Swift] UIView.init() 에 대하여
안녕하세여 여러분. 흠 원래 required init?(coder: NSCoder)
에 대해 쓰려다가 또 딴 길로 새버렸네유. 이 내용은 다른 곳에서도 충분히 잘 설명되어있는 것 같아서 그건 TIL에 개인적으로 정리하기로 하고..!
지금까지 UIView()
잘 써오셨나요?? 거두절미하고 UIView
의 문서에서 initializer 를 보자요.
맞아여 이렇게 두개예요. 읭?? 근데 나는 UIView()
이렇게도 써왔는데?!!?!?! 왜 init()
에 대한 설명은 없는겨..?
봐봐! 생성하려고 괄호 열면 떡하니 처음으로 나오는게 ()
생성자라고!! 그럼 이건 도대체 뭐다??? 오늘의 주제는 이런 의문점으로부터 시작합니다
흠.. UIView
의 문서에는 init()
을 코빼기도 찾아볼 수 없으니 Implemented by subclass 어쩌구저쩌구 써있는 설명으로 구글링을 해보자구요
오호.. 사실 얘는 NSObject
의 이니셜라이저였군요! 🤔
앗 UIView
에서 얘를 사용할 수 있다는건 어쨌든 NSObject
를 상속받고 있단거네 ?? ㅇㅇ 맞슴다. UIView
가 UIResponder
를 상속받고, 얘가 다시 NSObject
를 상속받고 있죠.
오호 ㅇㅋㅇㅋ! 그래도 init(frame:)
와 init(coder:)
두 개만이 UIView
의 Designated initializer (class를 위한 필수 initializer) 이기 때문에 UIView
를 생성하려면 이 둘 중 하나를 어디선가 반드시 호출해줘야겠져??
UIView()
로 뷰를 생성하면 내부적으로 init(frame:CGRect)
을 호출하게 됩니다.
저는 이걸 예전에 삽질하다가 알게 되었는데 진짜 그런지 아래와 같이 코드를 작성하고 CustomView
의 init(frame:)
부분에 디버그 포인터를 찍어봅시다리
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let view = CustomView()
}
}
class CustomView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
print(frame)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
좌측 디버그 네비게이터에서 콜스택 찍히는걸 보면 정말 init(frame:)
을 호출하고 있쥬? 참고로 이때 찍힌 frame은 (0.0, 0.0, 0.0, 0.0)
값을 가집니다
그럼 init(frame:)
으로 뷰를 생성한다면 어떻게 콜스택이 찍힐까요??
let view = CustomView(frame: CGRect(origin: .zero, size: CGSize(width: 100, height: 100)))
오호.. 좀 더 짧네요. 두 단계정도 줄어드는 것 같아요. 자세히 살펴봅시다
viewDidLaod
와 @objc CustomView.init(frame:)
사이에 init(frame:)
으로 생성한 것은
CustomView_allocationg_init(frame:)
를 호출하고
init()
으로 생성한 것은
UIView._allocationg_init()
@nonobjc UIView.init()
-[UIView init]
를 호출하고 있네여
흠 근데 콜 스택 찍힌 부분을 보면 아이콘들이 커피 모양도 있고, 사람 모양도 있네요??? 뭐지?? 싶어서 찾아봤슴다.
사람 모양은 유저 코드, 커피 모양은 AppKit / UIKit 쪽 코드라는 거였군요! 쏘 신기..
그럼 AppKit / UIKit
쪽 코드이자, @objc CustomView.init(frame:)
가 호출 되기 바로 전 단계인 -[UIView init]
에서 NSObject
의 init
을 override 한 후 init(frame:)
을 호출하는 거려나??? 정도의 생각이 드네욤. 구현된 코드를 볼 수 없는 이상 뇌피셜이긴 하지만여 ㅎ_ㅎ
튼 오늘의 결론은 UIView()
는 NSObject
의 initializer이고, 이렇게 UIView
를 생성하면 frame은 (0.0, 0.0, 0.0, 0.0)
인 상태로 UIView
의 Designated Initializer인 init(frame:)
이 호출된다! 입니다.
오늘의 글도 누군가에게는 도움이 되길 바라며 그럼 20000~~!