본문 바로가기

Swift/문법

[Swift] ARC

ARC

ARC는 iOS 면접 단골 질문입니다.

참조 타입과 HEAP

  • swif의 힙에 메모리는 인스턴스, 클로저 등등 참조 타입은 자동으로 힙에 할당한다.
  • 지금 까지 우리는 자동으로 할당하여 쓰고 있었음
class Man {
    var name: String?
    var age: Int?

    init(name: String?, age: Int?) {
            self.name = name
            self.age = age
    }
}

let a = Man(name: "ssss", age: 19)

스택 → 힙

  • 힙영역
    • Man instance
    • name = ssss
    • age = 19
  • 스택
    • a

지역 변수 a에 스택이 할당되고 실제 Man은 힙에 저장됨

스택에 있는 a는 힙 영역에 인스턴스를 참조하고 a 안에 힙에 할당된 인스턴스의 주소값이 있습니다.

let a = Man(name: "ssss", age: 19)
let b = a

이런 식으로 해주면 힙 영역의 인스턴스를 같이 바라보고 있을 것 입니다.

때문에 힙이라는 특징 중 하나는 사용하고 난 후에는 반드시 메모리를 해제 해주어야합니다.

그러면 지금까지 내가 iOS 개발을 하면서 힙 메모리가 있으니까 메모리를 해제해주어야지~ 라고 생각하면서 해본 적이 없을 것 입니다. 이제 이런 것을 해주는 친구가 ARC 입니다.

그럼 ARC란 무엇일까?

ARC의 존재 이유는 아까 위에서 설명한 것 같으니 따로 설명을 하지는 않겠습니다. 그래도 한번은 설명하겠습니다.

ARC

  • 클래스 인스턴스가 더 이상 필요하지 않을 떄 메로리를 자동으로 해제한다.
  • 힙에 할당된 인스턴스의 메모리를 알아서 관리해주는 친구
GC RC
참조 계산 시점 Run Time
- 어플 실행 동안 주기적으로 참조를 추적하여 사용하지 않는 instance를 해제함 Compile Time
- 컴파일 시점에 언제 참조되고 해제되는지 결정되어 런타임 때 그대로 실행함
장점 인스턴스가 해제될 확률이 높음 (RC 보다는) 개발자가 참조 해제 시점을 파악할 수 있음

RunTime 시점에 추가 리소스가 발생하지 않음 |
| 단점 | 개발자가 참조 해제 시점을 파악할 수 없음

RunTime 시점에 계속 추적하는 추가 리소스가 필요하여 성능 저하가 발생될 수 있음 | 순환 참조가 발생시 영구적으로 메모리가 해제되지 않을 수 있음 |

MAR? ARC?

  • MAR는 Manual
    • 힙에 메모리를 직접 할당
    • Objc에서 사용
  • ARC는 Automatic
    • 위에서 지금까지 설명한게 ARC

RC?

  • Reference Count
  • 인스턴스를 현재 누가 가리키고 있느냐 없느냐를 숫자로 나타낸 것
    • 참조 카운팅이 0이라는 것은 아무데서도 참조되지 않으니 필요없으니까~ 메모리를 해제하라는 뜻임
  • 모든 인스턴스는 RC를 가지고 있음

참조 횟수?

  • Count Up(+)

    • 인스턴스의 주소값을 변수에 할당할 때

    • 인스턴스를 새로 생성할 떄

      • 예제
      let a = Man(name: "asdf", age: 19)
    • 예를 들어서 변수에 인스턴스를 생성한 것을 넣으면 RC + 1

    • 기존 인스턴스를 다른 변수에 대입할 떄

      • 예제
      let b = a
    • 기존 인스턴스를 다른 변수에 대입할 때도 RC 값이 증가함

    • A = RC +1, B = RC + 1(같은 힙영역을 바라보고 있음)

  • Count Down

    • 인스턴스를 가리키던 변수가 메모리에서 해제되었을 때

      • 함수가 종료되어 지역변수 a가 스택에서 해제되는 순간 RC - 1

      • 예제

        func abc(_ bc: Man) {
          let c = bc
        }
        
        let d = Man(name: "asdf", age: 19)
      • 위의 경우 때 의 RC - 1이 되어서 힙영역에서 나감

    • nil이 지정되었을 때

      • (옵셔널 타입이라는 뜻)

      • 예제

        a = nil
        b = nil
      • nil을 해준다는 것은 RC의 값을 0으로 만든 다는 것과 같은 소리 입니다.

    • 변수에 다른 값을 대입한 경우

      • 그냥 값이 다른 것으로 바뀌었을 때를 말하는 것입니다.

      • 예제

        let a = 10
        let b = Man(name: "asdf", age: 19)
        
        b = a // RC - 1
      • b 변수에 주소가 바꼈으니 참조 카운터도 변하는 것은 당연합니다. RC가 0이 되었으므로 ARC에 으해 자동으로 메모리를 해제 시킴

'Swift > 문법' 카테고리의 다른 글

[Swift] 프로퍼티  (0) 2023.06.10
[Swift] 함수  (0) 2023.06.09
[Swift] 흐름 제어  (0) 2023.06.08
[Swift] 데이터 타입  (0) 2023.06.07
[Swift] 프로퍼티  (0) 2023.03.19