iOS 공부하면서 스토리보드에서 컴포넌트를 끌어다 놓을때

strong / weak 의 연결을 하는것을 알게되었고 이게 무슨의미인가.. 싶었지만

그냥 weak으로 해라! 라고만해서 그 의미에 대해 깊게 파악해보진 않았던거 같다..

그래서 이 강한참조 / 약한참조 의 근본(?)인 ARC 를 공부해보쟈!

 

What is ARC?

ARC 는 Automatic Reference Counting의 약자다!

ARC는 메모리를 스스로 관리하는 기능을 수행한다 일반적으로 Swift가 자동으로 ARC를 이용해 메모리를 관리하기 때문에 사용자는 메모리는 어떻게 처리해야하는지 깊게 생각할 필요는 없다고.. (공식문서에 써있다..)

💡 Objective-C 에서는 MRC 라고 하는 수동 메모리 관리 기법을 사용하였다, Objective-C 에서는 수동으로 관리해야 하기 때문에
retain / release 를 사용해 사용수의 증가/감소 를 확인하여 메모리를 관리하였는데 ARC 로 넘어오면서 이걸 자동으로 해준다! 그래서 프로그래머는 더이상 메모리관리에 관한 코드를 따로 작성하지 않아도 된다! 

그래서 ARC 어떻게 동작하는데?

Class 의 인스턴스가 생성될때마다, ARC는 해당 인스턴스에 대한 정보를 저장하는 Memory 할당하게 된다!

이 메모리는 당연히 인스턴스의 method, property 의 값 등의 정보를 가지고있다!

 

그리고 해당 인스턴스가 더이상 필요가 없어지면 해당 메모리를 확보하여 다른 목적으로 사용가능케한다!!

그러니까.. 한마디로 요약하면 “ Class가 필요 없어지면 해당 메모리를 해제함

 

그럼.. Class가 필요한지 필요없는지 어떻게 판단하게될까..? 이름에서 유추할수 있다!

해당 Class의 인스턴스가 참조되고 있는 수를 세어 가지고 있다!

이 수를 세기위해 클래스 인스턴스를 할당할 때마다 강력한(Strong) 참조를 하게되며, 이 강력한 참조가 유지되는 동안은 할당 해제를 허용하지 않게된다!

백문이 불여일견 직접 예시로 살펴보자

class OS {
    let kind: String
    
    // 초기화
    init(kind: String) {
        self.kind = kind
        print("[인스턴스 생성] 현재 운영체제는 \\(kind)")
    }
    
    // 소멸자
    deinit {
        print("[인스턴스 할당 해제] \\(kind) 운영체제 종료")
    }
}

일단.. Class를 맹글어 주고..

var os1: OS?
var os2: OS?
var os3: OS?

이렇게 하면 인스턴스가 생성이!!!!

안됩니다.

예 안돼요..

 

Optional 로 선언되어 있어서 기본적으로 nil 값이 할당되기 때문에 class 인스턴스를 할당하지 않아요!

os1 = OS(kind: "MacOS")
// [인스턴스 생성] 현재 운영체제는 MacOS

이제야 비로소 인스턴스가 할당되었습니다! 그러면 ARC에 의해 강한 참조로 os1 변수가 counting 될거에요!

os2 = os1
os3 = os1

이렇게 선언하면 강한참조로 counting이 2개더 더해지겠죠?!

 

자 그럼 할당을 해재해 볼거에요 우리는 할당을 해제하면서

print("[인스턴스 할당 해제] \\(kind) 운영체제 종료") 구문이 수행되기를 원합니다!

os1 = nil
os2 = nil

2개의 변수를 할당 해제했음에도 deinit 구문이 수행되지 않습니다.. 왜일까요?!

ARC에 의해 os3 에대한 reference count 를 가지고 있기 때문입니다!!

os3 = nil
// 인스턴스 할당 해제] MacOS 운영체제 종료

비로소 참조 수가 0이 되면서 deinit 이 수행된다!!

 

하지만 ARC를 사용하면서 메모리 누수 가 발생하는 상황이 반드시 나온다!

이를 방지하기 위해서 우리는 weak  unowned 의 개념을 알아야한다!

+ Recent posts