1. 문제 상황
작업중 UIView
를 상속받은 커스텀 뷰를 만드는 과정에서 super.init()
을 호출할 경우 오류가 발생하여 UIView()는 어떤 이니셜라이저를 호출하는지 의문이 생겨 찾아보았다.
class customView: UIView {
init() {
super.ini() //여기서 에러가 발생함. UIView는 UIView() 이렇게 초기화를 할 수 있었는데 대체 왜지??
}
}
2. 혹시 UIView에 convenience init()
이 있나?
구글링을 해보니 어느 블로그에서는 UIView()가 NSObject의 init()을 호출한다고 하였다.
그런데 아래와 같은 근거로, 이렇게 동작하지는 않는다고 판단하였다.
- superclass(NSObject)에서 subclass(UIView)의 designated init을 호출할 수 없다.
2023.10.22 - [iOS] - [iOS] designated init, convenience init 은 대체 뭘까??
[iOS] designated init, convenience init 은 대체 뭘까??
아주 간단히 요약하자면, 다음과 같다. 1. designated init(지정 생성자) 초기화에 반드시 필요한 생성자이다. 무조건 designated init이 불려야 객체가 생성된다. 2. convenience init(보조 생성자) 초기화에 반
pushedgun.tistory.com
- 위 내용대로 동작할 경우 커스텀 뷰의 이니셜라이저에서 super.init()에서 에러가 발생하지 않아야 한다.
UIView에 convenience init()이 존재하고 그 속에서 self.init(frame: CGRect)
를 호출한다는 결론을 내리니 모든 현상이 설명되는 것처럼 보였다.
super.init()에서 에러가 발생하는 이유
- UIView의 이니셜라이저는
init(frame: CGRect), init(coder: NSCoder)
두 가지이다. - subclass에선 superclass의 convenience init()를 호출할 수 없다. 따라서 UIView를 상속받은 커스텀 뷰는 UIView의
convenience init()
을 호출할 수 없기 때문에super.init()
을 호출할 수 없다.
super.init()이 컴파일 시간에는 에러가 발생하지 않고, 런타임 시간에만 에러가 발생하는 이유
- UIView가 상속받는 superclass 중 NSObject에 init()이 존재하기 때문에
super.init()
에서 컴파일 에러가 발생하지 않았다.
How come I can initialize a UIView without parameters, but its documentation does not have an empty initializer?
let view = UIView() Why does this compile without an error when the only documented UIView initializer is init(frame: CGRect)? Specifically, I am trying to write a new class that inherits from UIV...
stackoverflow.com
3. 결론: swift compile가 UIView는 인자없이 초기화가 가능하도록 init()을 생성해주었던 것이다.
콜 스택을 통해 확인해보니, @nonobjc 코드가 생기며, @objc init(frame:)이 불리는 것을 확인할 수 있다.
컴파일러가 인자없이 생성이 가능하도록 init()을 만들어주었던 것이다.
사실 이렇게 콜 스택을 통해 검증하는 방법이 익숙하지 않아서, 가지고 있던 지식들만을 활용해서 여러 가설들을 세웠었다.
무언가 그 원인을 잘 모르겠을 때, 콜 스택을 확인해 직접 확인해주는 방법을 자주 활용해보아야겠다.