inblog logo
|
오니의 개발 블로그
    Swift

    Swift 기본 정리 - ARC/Dispatch/Protocol/Generic

    기술면접 대비 Swift 정리편
    오니's avatar
    오니
    Jun 22, 2024
    Swift 기본 정리 - ARC/Dispatch/Protocol/Generic
    Contents
    ARC순환참조 찾는 방법autoReleasepoolValue Type | Refernece Type왜 value type이 Reference type보다 빠를까?Dynamic | Static DispatchDispatchclass 내 Dispatchstruct 내 Dispatch protocol 내 DispatchSwift의 Protocol은 어떻게 적용될까?Protocol 배열Existentical ContainerProtocol Argument 함수Swift의 Genericprotocol을 곁들인1️⃣ - 프로토콜 인자로 받음2️⃣ - Generic 인자로 받음

    ARC

    Automatic Reference Count
    • 컴파일 타임에 동작
    • Strong, weak는 ARC테이블을 통해 간접참조
    • unowned은 ARC테이블을 사용하지 않고 직접 참조한다.
     

    순환참조 찾는 방법

    1. Instrument - Leak
    1. Graph
    1. CFRetainCount로 디버깅
    1. 메모리 증감 살피기

    autoReleasepool

    - 해당 블록 내에서는 ARC 증감 내역을블록 종류 후에 반영한다.

    Value Type | Refernece Type

    왜 value type이 Reference type보다 빠를까?

    • Heap 메모리 선언시 오버헤드가 크기 때문이다.
      • Heap 메모리 저장하기 위한 Heap 메모리 탐색
      • Heap 저장한 메모리를 멀티 스레드에 sync 맞추기
      • 해제 과정도 멀티 스레드에 반영해야 함

    Dynamic | Static Dispatch

    Dispatch

    • 사전 뜻: 발송 → 어떤 함수를 실행 시킬 것인지 결정하는 것

    class 내 Dispatch

    • 기본적으로 dynamic
    • private / final 키워드가 붙으면 static
      • private → 상속이 불가능
      • final → 상속이 불가능
    • extension 내 함수 → static
      • 상속 및 override 불가능 → Static

    struct 내 Dispatch

    • static

    protocol 내 Dispatch

    • 기본적으로 dynamic

    protocol 선언 O / extension 구현 O / 객체 구현 O

    → Dynamic
    • 객체에 구현된 것이 우선적으로 적용됨으로 Dynamic

    protocol 선언 O / extension 구현 O / 객체 구현 X

    • Static
      • extension에 구현되었고 상속이 불가능 함으로 Static

    protocol 선언 X / extension 구현 O / 객체 구현 O

    • 상황에 따라 다르다.
      • protocol type의 객체 → Static (extension 사용)
      • protocol 상속받은 type → Dynamic (객체 사용)
      • protocol A { } extension A { func testFunc() { print("It's protocol") } } class B: A { func testFunc() { print("It's Object") } } let obj1: B = B() let obj2: A = B()
        obj1: B은 Dynamic obj2: A 는 Static으로 작동한다.

    Swift의 Protocol은 어떻게 적용될까?

    Protocol 배열

    • Protocol을 따르는 객체의 크기는 모두다 다른데 어떻게 메모리에 저장될까?
    → Existentical Container 활용

    Existentical Container

    notion image
    • Existentical Container는 위와 같이 구성됨

    Value Buffer

    • Value Buffer에 실질적으로 Protocol을 따르는 객체의 메모리가 올라가게 됨
      • 객체의 크기가 3word 이상이다? → 객체는 Heap에 저장되고 Value Buffer에는 주소 값을 갖게 됨

    Value Witness Table

    • 객체의 allocate deallocate copy destruct 를 맡음

    Ptorocol Witness Table

    • protocl 함수 구현부 위치를 갖고 있는 테이블

    Protocol Argument 함수

    Protocol을 따르는 함수인자를 받을 때 어떻게 적용되나?
    → Existentical Container로 넘긴다.
    → 그럼 그게 class랑 뭐가 달라?
    → COW를 활용하여 최대한 heap을 덜 사용한다.

    Swift의 Generic

    protocol을 곁들인

    // 1️⃣ struct A { init(a: Drawable, b: Drawable) } // 2️⃣ struct A<T: Drawable> { init(a: T, b: T) }
    이 2개는 어떻게 다를까?

    1️⃣ - 프로토콜 인자로 받음

    이 경우 Extential Container로 Protocol객체를 받는다. value Buffer가 클 경우에 heap이 사용된다.

    2️⃣ - Generic 인자로 받음

    Swift Complier에서 해당 Generic을 사용해 만들 수 있는 모든 생성자를 만듬
    protocol Pro { } class A: Pro { } struct B: Pro { } struct C<T: Pro> { init(a: T, b: T) }
    위 예시인 경우 Swift Complier가 아래와 같이 생성자를 만든다.
    struct C<T: Pro> { init(a: A, b: A) init(a: B, b: B) }
    위와 같이 생성자를 직접 만듬으로 컴파일 시간에서 빌드되게 만들어준다.
    → 그럼 코드가 너무 많이 늘어나느거 아님?
    사실상 최적화 때문에 사실상 오히려 코드가 줄어든다고 한다.
     
    Share article
    Contents
    ARC순환참조 찾는 방법autoReleasepoolValue Type | Refernece Type왜 value type이 Reference type보다 빠를까?Dynamic | Static DispatchDispatchclass 내 Dispatchstruct 내 Dispatch protocol 내 DispatchSwift의 Protocol은 어떻게 적용될까?Protocol 배열Existentical ContainerProtocol Argument 함수Swift의 Genericprotocol을 곁들인1️⃣ - 프로토콜 인자로 받음2️⃣ - Generic 인자로 받음

    오니의 개발 블로그

    RSS·Powered by Inblog