[iOS/Swift] Method Dispatch

·2024년 6월 17일
0

Swift 문법

목록 보기
1/16
class Parent {
    func method() {

    }
}

class Child: Parent {
    override func method() {

    }
}

let instance: Parent = Child()
instance.method()

여기 Parent를 상속하는 Child 클래스가 있다.
Parent 타입의 Child 인스턴스 생성 후 method 호출 시, 어떤 함수를 호출할까?

이때 어떤 함수를 호출할지 결정하는 매커니즘이 method dispatch이다.


Dispatch의 2가지 타입

[먼저 알아야 할 것]
컴파일 타임 vs 런타임 정의
컴파일 타임: 개발자의 소스코드가 기계어로 컴파일되는 과정
런타임: 컴파일 과정을 마친 프로그램이 실행되는 과정


Static Dispatch

  • 상속을 지원하지 않는 value type들의 dispatch 방식
  • 컴파일 타임에 어떤 메서드를 실행할지 분명하게 알고 있기 때문에 빠르게 수행
    상속을 지원하지 않기 때문에 어떤 메서드를 실행할지에 대한 고민이 필요가 없다.

Dynamic Dispatch

  • 런타임에 어떤 메서드를 실행할지 결정하기 때문에 오버헤드 발생 및 느림
  • 런타임에 실제 호출할 메서드의 주소가 저장된 vtable(Virtual Table)을 탐색해야 함.
  • 다형성(polymorphism)을 지원
class Parent {
    func method() {
        print("안녕 난 부모님...")
    }
}

class Child: Parent {
    override func method() {
        print("안녕 난 자식!")
    }
}

let p1 = Parent()
let p2 = Parent()
let c1 = Child()
let c2 = Child()

let people = [p1, p2, c1, c2]
for person in people {
    person.method()
}

/*
 안녕 난 부모님...
 안녕 난 부모님...
 안녕 난 자식!
 안녕 난 자식!
 */

비고)
Objective-C에서는 vtable 대신, Message Dispatch를 사용
메서드 호출 시 메세지를 전송하고, 런타임에서 시스템이 메세지를 받아 처리
이 과정에서 메서드를 동적으로 교체하는 것도 가능하다고 한다.
따라서 메서드 호출 시 가장 유연한 방식이라고 표현


Virtual Table(vtable)

  • 컴파일러가 테이블 생성
  • 클래스 메서드에 대한 함수 포인터 배열이 vtable
    = 모든 하위 클래스에는 override된 메서드를 포함한 vtable 존재
  • 하위 클래스에 새로운 메서드 추가 시, 해당 테이블의 끝에 추가된다
  • 런타임 시에 실제 타입의 vtable을 조회하여 알맞은 메소드 호출
class ParentClass {
    func method1() { }
    func method2() { }
}

class ChildClass: ParentClass {
    override func method2() { }
    func method3() { }
}

override된 method2 , 새로 추가된 method3 모두 하위 클래스의 vtable에 기록된다.




Reference

https://maxim-kryloff.medium.com/swift-method-dispatch-4ac7efab0388

0개의 댓글

관련 채용 정보