Skip to main content

Command Palette

Search for a command to run...

Swift의 Dispatch

Updated
Swift의 Dispatch
T

안녕하세요🙇🏻‍♂️ 세상을 더 편리하게 바꾸고 싶은 iOS 개발자 최인호입니다.

Hello 👋 I'm Inho Choi, an iOS developer who wants to change the world more conveniently.

  • 대학교 졸업
  • Apple Developer Academy @ POSTECH 1기
  • KWDC Main Organizer
  • AsyncSwift Organizer

~~ 런타임에 결정되는...

~~ 컴파일에 결정되는...

개발 문서를 보다보면 수 없이 마주치는 런타임과 컴파일!

런타임과 컴파일은 뭔지 알겠다. 그럼 그걸 결정하는 기준이 무엇일까?

Dispatch

  • Dispatch는 어떤 코드를 실행하는지 결정하는 메커니즘이다.

  • 즉, 런타임과 컴파일을 결정하는 메커니즘이 Dispatch이다.

  1. Static Dispatch -> 컴파일 시간에 실행할 함수를 결정함

  2. Dynamic Dispatch -> 런타임 실행할 함수를 결정함

Static Dispatch

컴파일 타임에 컴파일러가 어떤 메소드를 실행할지 주소값을 알고 있음

별도 과정 없이 inline으로 실행됨

아 이 함수는 그 서울시 토비로 103 건물 304호에 Toby라는 사람 있어 그 사람에게 코드 받으면 돼!

Dynamic Dispatch

런타임에 어떤 메소드를 실행할지 Swift는 V-Table을 이용하여 실행할 코드를 결정한다.

V-Table을 찾아서 실행할 코드를 사용시 마다 참조하기에 Static 보다 느리다.

아 이 함수는 그 서울시 토비로 103 건물 어딘가에 Toby라는 사람 찾아서 그 사람에게 코드 갖고와.

어떠한가? 예시 문장을 보자

Static Dispatch는 정확한 주소를 제공함으로 가져오는데 시간이 절약되지만,

Dynamic Dispatch는 건물에 가서 Toby라는 사람을 찾고 갖고 와야한다.

건물이 단층이라면 다행이지만 100층짜리 아파트라면? 엄-청 시간 오래 걸릴 것이다.

그럼 왜 Dynamic을 사용하는 것일까?

\=> 함수 실행요건에 따라서 달라지는 경우가 생길 수 있음

예를 들면, 클래스 상속! 실행 될 때에 따라서 업캐스팅이 되었는지 다운 캐스팅이 되었는지 둘 다 아닌지 상황 판단을 해야함

컴파일에는 미리 결정할 수 없음으로 런타임 시간에 결정해야 함

\=> 외부 라이브러리를 불러 올 때

외부 라이브러리를 불러올 때 Static, Dynamic 선택할 수 있게 만든 라이브러리가 종종 있음

이 때 비용을 생각해가면서 Static, Dynamic을 선택해야 함

엥? 이상하다 Static이 빠르다며 근데 왜 비용을 고려해?

Static으로 분류된 라이브러리를 갖고오면 코드를 통째로 컴파일에 올려버린다.

즉 용량이 되게 커버린다. 그리고 빌드타임이 굉장히 오래 걸린다.

반면, Dynamic은 실시간으로 코드를 가져오기 때문에 용량이 작다.

이러한 장단점을 비교해가며 선택해야 한다.

그럼 예시를 통해서 알아보자

예시를 통한 Static, Dynamic

Protocol

protocol Animal {
    func cry()
}

class Dog: Animal {
    func cry() {
        print("멍멍")
    }
}

class Cat: Animal {
    func cry() {
        print("야옹")
    }
}

let object: Animal = Dog()
object.cry()

위 코드에서 func cry()는 Dynamic일까? -> YES

왜냐하면 func cry()의 같은 경우 어떤 곳에서 코드를 가져와야 할지 확인해야하기에 Dynamic

protocol Animal {
    func cry()
}

extension Animal {
    func birth() {
        print("동물이 탄생했습니다!")
    }
}

그럼 여기서 birth는 Dynamic 일까? Static 일까?

정답은 Static이다. 왜냐하면 protocol 채택하는 곳 상관 없이 모두 동일하게 작동되기 때문이다.

값 타입, Value 타입

값 타임에서는 상속이 불가능하기에 Static Dispatch가 사용

Class

protocol Animal {
    func cry()
}

extension Animal {
    func birth() {
        print("동물이 탄생했습니다!")
    }
}

class Dog: Animal {
    func cry() {
        print("멍멍")
    }

    func birth() {
        print("강아지가 탄생했습니다!")
    }
}

class Cat: Animal {
    func cry() {
        print("야옹")
    }
}


let object: Animal = Dog()
object.cry()
object.birth()

Dog의 cry함수는 Dynamic -> 프로토콜을 채택 받아서 사용하기 때문에

Class + extension 은? 이 같은 경우도 Protocol 과 같이 상속받는 것과 상관 없이 작동하기에 static

그럼 개발자가 확실하게 Static으로 변경할 수 있도록 만들 수 없을까?

그럼 여기서 바로 중요한 키워드가 나옴 바로 final 이라는 키워드임

final 이란?

더 이상 상속하지 않는다면 Dynamic으로 계산할 필요가 없음

  • 그래서 final로 선언한 클래스는 Static으로 작동한다.

스위프트는 역시 똑똑해 WHO(Whole Module Optimization)

모듈 전체를 컴파일 하여서 internal level에서 오버라이딩 되는지 안되는지 추론 하여서 오버라이딩 가능성이 없는 경우 내부적으로 final을 붙여서 계산한다.

  • WHO가 적용될 수 없는 경우 open public추론상 무조건 dynamic으로 한다.

  • 외부에서 사용(public) 외부에서 오버라이딩(open) 가능성이 있음

코드의 dynamic은 무엇일까?

  • Objective-C 런타임 시간에 Dynamic Dispatch를 적용 받기 위해 사용된다.

  • @objc 와 비슷하다.

    *objc는 Objective-C에서 API를 사용할 수 있도록 하는 속성


참조한 사이트

More from this blog

[CS] Https는 대칭키일까? 비대칭키일까?

결론: 둘 다 쓴다. 하지만 쓰는 타이밍은 다르다. 자세하기 알아보자. 혹시 모르니 용어는 정리해두자. 암호화 <-> 복호화 해독 = 복호화 비대칭키 해독은 대칭키 해독보다 오래 걸린다. 비대칭키를 쓰는 과정 💡 비대칭키는 대칭키를 만들기 위한 여정에 쓰인다. 뭔 소리지??? 대칭키를 만들기 위해서 비대칭키가 쓰인다고?? 비대칭키 해독은 대칭키 해독보다 오래걸린다. 1. Client가 Server에 접속을 요청하면 서버는 Secret ...

Jun 6, 202417

Xcode Cloud 사용 후기

애플에게 내는 친구비를 내며 Apple Developer 계정을 유지하려면 매년 애플에게 13만원의 친구비를 지불해야한다. 그리고 몇 개 친구 답례 상품을 주는데 그 중 하나가 Xcode Cloud 상품 주는데 안 쓸 이유는 없지 Xcode Cloud 개인에게는 과연? K-Spam 이라는 앱을 오랫동안 구상하고 드디어 출시를 했다. 생각보다 삽질을 많이 한 것 같다. 하지만 사이드 프로젝트의 진정한 의미는 삽질(?)하며 배우는 것이 아니겠나 개...

Jun 3, 202418

iOS Version 주의

앱 버전에는 상위버전이 출시한 상태에서 하위 버전을 아카이브 할 수 없음 예를 들어 출시한 버전이 1.3 이면 1.2로는 아카이브가 불가능함 단, 출시한 적이 없는 앱이라면 버전은 마음대로 지정 가능 App Store Connect의 버전 예를 들어 1.03 이랑 1.1 이랑 비교하면 앱 버전은 1.03 > 1.1 로 인식한다. . 단위로 잘라서 Int로 인식하는 것 같다. 그러니 0은 최대한 사용하지 않고 구분한다면 . 으로 구분해야겠다.

Jun 1, 20248

Toby의 iOS 블로그

34 posts

안녕하세요 세상을 더 편리하게 바꾸고 싶은 iOS 개발자입니다.