개발하자 중엽아
  • [Swift] final
    2024년 08월 07일 16시 44분 18초에 업로드 된 글입니다.
    작성자: 이중엽

    final

    final은 Swift에서 class, method, property의 재정의 및 상속이 될 가능성이 없을 때 사용된다.

     

    final 키워드를 사용하는 이유

    final을 통해 기대할 수 있는 효과는 다음과 같다.

     

    • 코드 안정성
    • 성능 개선

    코드 안정성

    기본적으로 class, method, property는 아래와 같이 재정의가 가능하다.

    class Animal {
        
        var age: Int = 10
        
        func changeAge() {
            age = .random(in: 0 ... 100)
        }
    }
    
    class Dog: Animal {
        
        // 저장 프로퍼티는 getter/setter를 모두 사용해주어야 상속이 가능하다.
        override var age: Int {
            get {
                return ...
            }
            set {
                ...
            }
        }
        
        override func changeAge() { }
    }

     

    이때 final 키워드를 붙이면 재정의가 불가해진다.

     

    class Animal {
        
        final var age: Int = 10
        
        final func changeAge() {
            age = .random(in: 0 ... 100)
        }
    }
    
    class Dog: Animal {
        
        // 저장 프로퍼티는 getter/setter를 모두 사용해주어야 상속이 가능하다.
        override var age: Int {		// ❗️재정의 불가능 오류 발생
            get {
                return ...
            }
            set {
                ...
            }
        }
        
        override func changeAge() { }	// ❗️재정의 불가능 오류 발생
    }

     

    final로 선언된 클래스는 상속이 불가능하기 때문에 해당 클래스가 의도한 대로 사용되도록 보장한다.

    특정 클래스를 상속하여 의도하지 않은 동작을 하거나, 기존의 메서드를 오버라이드하여 원치 않는 동작을 수행하는 것을 방지할 수 있다.

     

     

    성능 개선

    final로 선언된 method, property는 런타임에서 동적 디스패치(Dynamic Dispatch)가 아니라 컴파일 시점에 정적 디스패치(Static Dispatch)를 사용하여 method 호출이 더 빠르고 효율적이다.

     

    여기서 말하는 Dispatch는 하나의 동작 매커니즘으로, 동적 디스패치 정적 디스패치로 나뉘어 진다.

    이 둘은 어디서 어떻게 method를 호출할 것인지를 결정하게 된다.

     

    동적 디스패치(Dynamic Dispatch)

    동적 디스패치를 사용하면 런타임에 호출될 함수가 결정된다

    원리는 Swift에서는 클래스마다 함수 포인터들의 배열인 vTable(Virtual Methon Table)을 유지하는데,

    하위 클래스가 메서드를 호출할 때, 이 vTable 를 참조하여 실제 호출할 함수를 결정한다

     

    이 과정들이 앱이 실행되는 런타임 시점에 결정되기 때문에, 컴파일 시점에 결정되는 정적 디스패치보다 성능적으로 손해를 보게 된다.

     

    정적 디스패치(Static Dispatch)

    정적 디스패치를 사용하면 컴파일 시점에 호출될 함수가 결정된다

    이때는 vTable이 아니라 해당 메소드의 주소를 직접적으로 참조하게 된다.

     

    이 방식은 컴파일 시점에 결정되기 때문에, final을 붙이지 않은 경우보다 더 빠르게 동작하여 성능 개선을 볼 수 있다.

     


    재정의하지 않는 mehod, property에 대하여 final을 붙여도 되지만,

    class 자체를 final로 지정하게 되면, 하위 method, property들은 자동으로 재정의될 일이 없기 때문에

    자연스럽게 정적 디스패치가 동작한다.

    'Swift' 카테고리의 다른 글

    [Swift] LayoutSubivews  (0) 2024.08.08
    [Swift] View Life Cycle  (0) 2023.06.11
    [Swift] App Life Cycle  (0) 2023.06.11
    댓글