# 인스턴스/타입 메서드 https://www.notion.so/yehaha/AnyObject-5beb26e4dc434df3b8c6b0ecf0585428 >> 여기 복붙해서 올려주세요~!! ## 허황, 나무 ### 질문 1. instance 메서드와 class 메서드의 차이점을 설명하시오. - 답변 > instance 메서드는 Class, Struct, Enum 인스턴스에 속해있는 메서드를 의미한다. Class, Struct, Enum 형태의 타입이 실체화하여 인스턴스가 생성됐을 때 호출 할 수 있는 메서드이다. class 메서드는 클래스의 인스턴스가 생성되지 않아도 클래스를 통해서 직접적으로 호출할 수 있는 메서드이다. 클래스에서만 사용가능하며, static 메소드와의 차이점은 클래스는 상속을 받을 수 있기 때문에 오버라이드 할 수 있는 static 메서드를 class 메서드라 한다. ### 질문 2. class 메서드와 static 메서드의 차이점을 설명하시오. - 답변 > class 메서드와 static 메서드 두 메서드 모두 인스턴스를 생성하지 않고 타입 자체에서 호출 할 수 있는 메서드이다. static 메서드는 class, struct, enum에서 모두 사용가능하며, class 메서드는 class에서만 사용가능하다. 클래스는 상속이라는 특성 때문에 부모 클래스의 타입 메서드를 오버라이드 할 때 사용가능한 메서드이다. 꼬리질문 ### 오버라이딩는 무엇인가? - 답변 >슈퍼 클래스의 인스턴스 메서드, 타입 메서드, 인스턴스 프로퍼티, 타입 프로퍼티, 서브스크립트를 상속 받은 하위 클래스에서 재정의 할 수 있는 기능이다. ### 오버라이드를 사용할 때 주의할 점? - 답변 > override 키워드를 붙여야한다. 슈퍼클래스에 선언된 메서드의 정의가 일치해야한다. 저장 프로퍼티로 재정의 할 수 없다. ### 타입 프로퍼티는 메모리 상 어디에 할당되는가? ![](https://i.imgur.com/ejjaXmY.png) - 답변 > data 영역에 저장된다. ### Static Property는 언제 초기화되는가? 첫 호출 시점에 초기화된다. 프로그램이 시작됐을 때 Inner 클래스 init() 내부 프린트문이 출력되지 않는다. ```swift // 테스트 코드 class SomeClass { static let a = Inner() } class Inner { init() { print("asdf") } } ``` ### 타입 프로퍼티를 사용할 때 Thread관점에서 주의할 점은? - 답변 > var로 선언하여 mutable한 경우, race condition을 주의하여 구현해야 한다. ## 호박, 애플사이다 ### 질문1. instance 메서드와 type 메서드의 차이점을 설명하시오. - instance 메서드 : 특정 타입의 인스턴스를 초기화한 뒤, 해당 인스턴스가 호출 가능한 메서드이다. - type 메서드 : 인스턴스 초기화 필요 없이, 특정 타입 자체만으로 호출 가능한 메서드이다. 메서드 앞에 static 또는 class 키워드를 붙인다. class 키워드는 클래스 타입에만 사용 가능하다. - (꼬리질문) 메서드가 무엇인가요? 클로저, 함수, 메서드의 차이는? - 클로저 : input을 처리하여 output을 반환하는 등 “특정 작업을 수행하는 코드 묶음”이다. - 함수 : 이름이 있는 클로저이다. - 메서드 : 특정 타입과 연관된 함수이다. - (꼬리질문) 어떤 경우에 타입 메서드를 사용하나요? 1. decode / encode 메서드를 구현한 JSONParser 타입 등의 uility 기능을 구현할 때 간단한 기능인데 자주 사용해서 인스턴스를 매번 생성하는게 번거로울 때, 프로퍼티 없이 메서드로만 구성된 경우 사용한다. 2. 열거형 namespace를 사용할 때 인스턴스 생성 없이 static let으로 타입 프로퍼티를 사용 (case가 없는 열거형은 인스턴스화되지 않음! static let같은 타입 프로퍼티가 있어도 안되니까 안전함) 3. 자주 쓰는 UI요소가 있을 때, 열거형에 Factory 메서드를 생성하여 사용함. 상태 값이 없음 4. DataFormatter는 생성 비용이 높으므로 여러 코드에서 타입 프로퍼티로 하나만 사용 (타입 프로퍼티 말고 싱글턴으로 쓰기도 함) - (꼬리질문) 인스턴스/타입 메서드 내부에서 self를 사용하면 무슨 뜻인가요? self는 암시적 프로퍼티이다. - 인스턴스 메서드의 self : 자신 인스턴스를 가르킨다. can assign an entirely new instance to the implicit `self` property. ```swift struct Point { var x = 0.0, y = 0.0 mutating func moveBy(x deltaX: Double, y deltaY: Double) { self = Point(x: x + deltaX, y: y + deltaY) } } ``` - 타입 메서드의 self : 자신의 타입 자체를 가르킨다. - (꼬리질문) 열거형에도 인스턴스/타입 메서드를 생성할 수 있나요? 인스턴스/타입 메서드 모두 가능하다. ### 질문2. class 메서드와 static 메서드의 차이점을 설명하시오. - class : superclass의 해당 메서드를 override 가능하다. 클래스에만 붙일 수 있다. - static : ~불가하다. - (꼬리질문) override이 무엇인가요? overload와의 차이점은? - override (재정의) : 상속받은 부모클래스의 기능을 자식클래스에서 다시 정의함 - overload (중복선언) : 이름은 같지만 시그니처(파라미터 수, 타입) 데는 다른 메소드를 중복으로 선언 - (꼬리질문) class 앞에 붙는 키워드 중에 final은 무슨 뜻인가요? 성능에 어떤 영향을 미치나요? final 키워드는 메서드, 프로퍼티, 타입 앞에 붙을 수 있다. 타입 앞에 붙은 final은 해당 타입의 상속을 방지하는 키워드이다. 클래스의 dynamic dispatch를 static dispatch로 바꿔주므로 성능이 향상된다. 타입 앞에 final을 붙이면 메서드, 프로퍼티 모두 override가 안되니까 static dispatch로 동작하게 된다. (값 타입은 상속을 안하므로 모두 static dispatch) 오버라이딩한 메서드는 런타임에 VTable (부모클래스의 메서드, 자식클래스의 메서드 중 뭘 호출해야할지 따져봐야 함)을 통해 어떤 메서드를 실행할지 결정 (dynamic)하는 반면, final 키워드가 적용된 메서드는 컴파일 시점에 어떤 메서드를 실행할지 결정 (static)하기 때문에 성능이 좋다. - (꼬리질문) VTable이란? - Swift는 클래스마다 VTable을 가진다. - 런타임 시점에 메서드 오버라이딩에 따라 실행 시점에 어떤 메서드를 실행할 지 결정하는 dynamic dispatch를 지원하기 위해 사용하는 메커니즘이다. - 가상메서드 테이블 (Vertual Table) - 함수 포인터들의 배열로 표현된다. - (꼬리질문) 구조체 메서드에 mutating 키워드를 붙이는 이유는? 기본적으로 값 타입 (구조체, 열거형)은 인스턴스 메서드를 통해 프로퍼티의 값을 변경할 수 없다. 하지만 메서드에서 저장 프로퍼티 값을 바꾸고 싶다면? 해당 프로퍼티는 var로 선언하고, 해당 구조체 인스턴스는 변수에 할당해야 한다. - 프로퍼티를 let으로 할당하면, 상수이므로 값을 바꿀 수 없다. - 인스턴스를 let으로 할당하면, “불변 인스턴스”이므로 프로퍼티가 변수이더라도 값을 변경할 수 없다. ```swift // 가변 인스턴스 생성 var mutable: Sample = Sample() // Sample 타입의 가변 인스턴스 생성 (var) mutable.mutableProperty = 200 // 가변 인스턴스 프로퍼티이므로 수정 가능 //mutable.immutableProperty = 200 // 불변 인스턴스 프로퍼티는 수정 불가하므로 컴파일 오류 // 불변 인스턴스 생성 let immutable: Sample = Sample() // Sample 타입의 불변 인스턴스 생성 (let) //immutable.mutableProperty = 200 // 불변 인스턴스는 아무리 가변 프로퍼티라도 수정 불가하므로 컴파일 오류 //immutable.immutableProperty = 200 ```