heoblitz
Blitz.dev
heoblitz
전체 방문자
오늘
어제
  • 분류 전체보기 (36)
    • iOS Dev (22)
      • iOS (3)
      • Swift (7)
      • Testing (3)
      • Reactive (2)
      • Architecture (2)
      • Layout (1)
    • PS (4)
      • Algorithm (4)
    • Other (9)
      • Springboot (3)
      • Linux (1)
      • Python (1)
      • Java (1)
      • React (1)

블로그 메뉴

  • 홈
  • 태그
  • 미디어로그
  • 위치로그
  • 방명록

공지사항

인기 글

태그

  • codingtest
  • Code Review
  • xcode
  • springboot
  • gradle
  • ARC
  • github
  • 오픈소스
  • java
  • SWIFT
  • chrome-extension
  • Test Code
  • URLSession
  • XCTest
  • swift 윈도우
  • swift 5
  • IOS
  • Git
  • intellij
  • RxSwift

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
heoblitz

Blitz.dev

Swift ARC ( Automatic Reference Counting ) 정리
iOS Dev/Swift

Swift ARC ( Automatic Reference Counting ) 정리

2020. 10. 7. 11:40

Photo by Nareeta Martin on Unsplash

 

추상적으로 "메모리를 관리해주는 것" 으로 이해하고 있었지만, JAVA 의 GC ( 가비지 컬렉터 ) 와의 차이점을 명확하게 설명하게 어려워서 포스팅을 작성했습니다.

 

 

프로그래밍 언어의 메모리 관리

 

C, C++ 과 같은 언어는 Heap 영역에 할당된 메모리를 개발자가 직접 관리하지만 대부분의 현대적인 언어들은 포인터를 언어 내부적으로 사용하고 ( 감추고 ) 메모리를 자동적으로 관리합니다. 이에 크게 두가지 방식이 있습니다.

 

RC ( Reference Count )

사용 언어: Swift, Rust ...

참조 시점: Complie time

 

특정 객체가 참조되면 Count 를 1 증가시키고, 반대로 참조 해제되어 Count 가 0이 되면 메모리에서 객체를 해제하는 기술입니다. 

 

장점 : 컴파일 시점에 적용되므로, GC 대비 효율적입니다.

단점 : 순환 참조가 발생되어, Memory Leak 이 발생할 수 있습니다.

 

GC ( Garbage Collection )

 

사용 언어: Java, C# ...

참조 시점: Run time

 

런타임에 별도로 Garbage 를 관리하는 리소스를 실행합니다. 해당 리소스가 자동적으로  힙에 있는 객체를 해제하는 기술입니다.

 

장점 : 개발자가 별도로 동적 객체 관리할 필요가 없습니다.

단점 : 런타임에 객체를 추적, 해제하는 과정에서 오버헤드가 발생합니다. 또한 추가적인 메모리 소모가 존재합니다.

 

 

Swift ARC 에 대해서

 

Swift 는 RC 중 ARC (Automatic Reference Count) 라는 메모리 관리 기법을 사용합니다. 컴파일시에 동작하고 자동적으로 Release 코드를 중간에 넣어주어서 객체를 메모리에서 해제합니다. 수동적인 방법은 MRC (Manual Reference Count) 로서 Objective-c 에서 사용되었습니다.

 

RC 를 이용한 메모리 관리 기법은 GC 대비 효율적이지만 개발자가 메모리 구조에 대한 이해가 필요합니다. 단점으로는 개발자의 실수에 의하여 순환참조를 발생시킬 수 있습니다.

 

 

Swift 강한 순환 참조가 발생하는 경우

1. 프로퍼티에서 다른 인스턴스를 참조하는 경우

 

위 예제는 프로퍼티에서 각 인스턴스를 참조하여 Counting 이 1씩 증가한 경우입니다.

인스턴스 참조 변수를 nil 했기 때문에 내부 프로퍼티에 접근이 불가한 경우로 Memory Leak 이 발생합니다.

 

 

2. 탈출 클로저(Escaping Closure), 딜레이가 있는 클로저(Closure) 에서 참조하는 경우

클로저는 Heap 에 생성되며, 필요한 변수를 Capture 하는 동작을 수행합니다. 위 상황에서 Self를 Capture 하였기 때문에 Reference Counting 이 1 증가하게 되고 tom 에 nil 을 대입하여도 인스턴스가 해제되지 않습니다.

 

 

 

Swift 에서 강한 순환 참조를 방지하는 방법

1. 미소유 참조 (Unowned), 약한 참조 (weak) 사용하기

Unowned 혹은 weak 키워드로 인스턴스를 참조하면 Reference Counting 이 올라가지 않습니다.

Unowned 은 해당 인스턴스가 존재함을 확신할 때 사용하고 ( 생명주기가 더 길때 )

 

weak 는 옵셔널 타입으로, 인스턴스가 존재하지 않는 경우에 Optional Binding 혹은

Chaining 으로 크래시를 방지할 수 있습니다. ( 옵셔널 타입 )

 

 

2. Closure 에서 Capture List 작성하기

Capture List 는 Closure 가 참조할 대상과 참조 방식을 지정하는 형식입니다. 

참조 타입이 아니라면 해당 요소는 클로저가 생성될 때 초기화 되지만 ( Value Type ) 그 외의 경우에는 Unowned, Weak 를 통해 얼마나 강하게 Capture 할지 지정할 수 있습니다.

 

 

Swift 는 Objective-c 처럼 직접 Reference Counting 을 관리해주지 않아도 되서 무척 편리하지만 다른 인스턴스를  참조할 때 메모리 구조에 대하여 한번 더 생각하고 참조 타입을 지정해야겠다는 생각을 했습니다. 

 

https://medium.com/flawless-app-stories/you-dont-always-need-weak-self-a778bec505ef

 

클로저를 사용할 때 어떤 상황에서 weak 를 사용해야 하는지를 도표로 나타낸 사진입니다.

 

 

 

 

참고: https://medium.com/flawless-app-stories/you-dont-always-need-weak-self-a778bec505ef

 

 

 

 

'iOS Dev > Swift' 카테고리의 다른 글

iOS JSON 을 Decoding 하는 여러 가지 방식들  (0) 2021.08.26
지금까지 받았던 코드 리뷰 정리 ( iOS, Swift )  (0) 2020.11.10
Swift Optional ( enum, wrapped ) 정리  (0) 2020.10.12
윈도우 10 에서 Swift 5 사용하기 ( Visual Code, WSL )  (4) 2020.08.01
iOS "UITableView Section Header 로드되지 않는 문제" 해결  (0) 2020.07.26
    'iOS Dev/Swift' 카테고리의 다른 글
    • 지금까지 받았던 코드 리뷰 정리 ( iOS, Swift )
    • Swift Optional ( enum, wrapped ) 정리
    • 윈도우 10 에서 Swift 5 사용하기 ( Visual Code, WSL )
    • iOS "UITableView Section Header 로드되지 않는 문제" 해결
    heoblitz
    heoblitz
    iOS, Swift 관련 포스팅을 주로 작성합니다.

    티스토리툴바