정보
Static Dispatch vs Dynamic Dispatch
밤새는 탐험가89
2024. 12. 13. 11:36
Static Dispatch와 Dynamic Dispatch는 메서드 호출 방식에 대한 개념으로, 프로그램이 메서드 호출 시점을 언제 결정하느냐에 따라 구분됩니다.
두 가지는 각각 컴파일 시간과 런타임에 메서드 호출을 결정하는 방식을 설명하며, 이로 인해 성능과 동작 방식이 다릅니다.
Static Dispatch (정적 디스패치)
- 컴파일 시간에 어떤 메서드를 호출할지 결정합니다.
- 호출 대상이 고정적이며, 런타임에 동적으로 결정되지 않습니다.
- 함수의 실제 구현은 호출 시점에서 이미 컴파일러가 알고 있습니다
- Static Dispatch는 값 타입(구조체, 열거형)의 메서드 호출과 컴파일 시점에 메서드 호출이 확정되는 경우에 사용됩니다.
1. 구조체(struct)와 열거형(enum)의 메서드
- Swift에서 구조체와 열거형은 값 타입이며, 상속과 다형성을 지원하지 않습니다.
- 이러한 경우, 메서드 호출이 컴파일 시점에 고정되므로 Static Dispatch가 사용됩니다.
struct Point {
var x: Int
var y: Int
func display() {
print("Point at (\(x), \(y))")
}
}
let point = Point(x: 10, y: 20)
point.display() // Static Dispatch
2. final 클래스 메서드
- final 키워드를 붙인 메서드는 상속이나 오버라이딩이 불가능합니다.
- 컴파일러는 final 메서드를 Static Dispatch로 호출해 최적화합니다.
class Animal {
final func makeSound() {
print("Generic animal sound")
}
}
let animal = Animal()
animal.makeSound() // Static Dispatch
Dynamic Dispatch (동적 디스패치)
- 런타임에 어떤 메서드를 호출할지 결정합니다.
- 호출 대상이 유연하며, 상속, 다형성, 프로토콜 준수 등의 기능을 지원합니다.
- 객체의 실제 타입에 따라 메서드가 동적으로 호출됩니다.
- Dynamic Dispatch는 클래스, 다형성(polymorphism), 그리고 프로토콜의 런타임 구현이 필요한 경우 사용됩니다.
1. 클래스 상속과 오버라이딩
- 클래스 메서드는 기본적으로 Dynamic Dispatch를 사용합니다.
- 메서드가 오버라이딩될 수 있기 때문에, 런타임에 객체의 실제 타입에 따라 적절한 메서드가 호출됩니다.
class Animal {
func makeSound() {
print("Generic animal sound")
}
}
class Dog: Animal {
override func makeSound() {
print("Woof")
}
}
let animal: Animal = Dog()
animal.makeSound() // "Woof" (Dynamic Dispatch)
2. 클래스 기반 프로토콜
- 프로토콜이 클래스에 의해 구현되면 Dynamic Dispatch가 사용됩니다.
- 특히, Objective-C와의 호환성을 위해 @objc 속성이 붙은 프로토콜 메서드는 항상 Dynamic Dispatch를 사용합니다.
@objc protocol Speaker {
func speak()
}
class Person: Speaker {
func speak() {
print("Hello!")
}
}
let speaker: Speaker = Person()
speaker.speak() // "Hello!" (Dynamic Dispatch)
3. 다형성(polymorphism)
- 런타임에 객체의 실제 타입에 따라 적절한 메서드 호출이 필요할 때 Dynamic Dispatch가 사용됩니다.
- 이는 상속과 오버라이딩이 필요한 코드를 작성할 때 자연스럽게 발생합니다.
4. Swift에서 @objc 속성
- Objective-C와 호환되도록 작성된 메서드나 프로토콜 메서드는 Dynamic Dispatch를 강제합니다.
Swift의 최적화 전략
Swift는 가능한 경우 Static Dispatch를 사용하여 성능을 최적화합니다.
하지만 런타임 동작(상속, 다형성 등)이 필요할 경우 Dynamic Dispatch로 자동 전환됩니다.
💡 개발자가 명시적으로 선택할 필요는 없으며, 코드 설계에 따라 적절한 방식이 선택됩니다.
예를 들어, 상속이나 다형성을 사용할 경우 Dynamic Dispatch가, 그렇지 않을 경우 Static Dispatch가 자연스럽게 사용됩니다.