[Swift] Dispatch / Static Dispatch / Dynamic Dispatch

2026. 2. 11. 16:07🍏/Swift

Dispatch ? 

"어떤 메서드를 호출할지 언제 결정하느냐"의 문제

player.move()

이 코드에서 실제로 어떤 move가 실행될지

  • 컴파일 타임에 결정되면 -> 정적 디스패치
  • 런타임에 결정되면 -> 동적 디스패치

정적 디스패치(Static Dispatch)

컴파일 시점에 호출될 함수가 결정되는 방식

  • 빠름 (함수 주소가 이미 결정됨)
  • 인라이닝 가능
  • 오버헤드 거의 없음
  • 다형성 X
// 값 타입 (struct / enum)
struct Player {
    func move() {
        print("move")
    }
}

// final class 메서드
final class Player {
    func move() {}
}

// private / fileprivate 메서드
class Player {
    private func move() {}
}

// extension 메서드 (class에서 override 안 되는 경우)
class Player {}

extension Player {
    func move() {}
}

 

성능 특성

  • 성능 특성
  • 직접 함수 주소 호출
  • vtable 탐색 없음
  • 메모리 접근 최소화
  • CPU branch prediction 유리

동적 디스패치 (Dynamic Dispatch)

런타임에 실제 객체 타입을 보고 호출 함수 결정하는 방식

  • 비교적 느림
  • 다형성 O
  • ovveride 가능
  • 유연성 높음
// class + override
// vtable 기반 동적 디스패치
class Animal {
    func speak() {}
}

class Dog: Animal {
    override func speak() {}
}

// protocol (existential 타입)
// witness table 기반 동적 디스패치
protocol Moveable {
    func move()
}

func run(_ object: Moveable) {
    object.move()
}

// @objc / dynamic
// Objective-C runtime 기반 (메시지 디스패치)
// 가장 느림
class Player: NSObject {
    @objc dynamic func move() {}
}

 

내부 동작 차이

방식 내부 메커니즘 속도
정적 direct call 가장 빠름
class vtable 빠름
protocol witness table 중간
@objc dynamic objc_msgSend 가장 느림