iOS/기초 지식

어..어어..!! 순환참조!

minaje 2023. 10. 17. 14:04

Swift의 메모리 관리

Retain Cycle(순환참조)을 살펴보기 전에 Swift의 메모리 관리에 대해 알아야한다!
다행히도 ARC (Auto Reference Counting)는 대부분의 메모리 관리를 자동으로 해줍니다! 
자! 그러면 ARC가 어떤 원리인지 알아봅시다.

ARC의 원리

기본적으로 클래스의 객체를 가르키는 각각의 reference는 강한 참조입니다!
그리고 최소 하나의 강한 참조가 있는 이상 객체는 메모리에서 해제되지않습니다.

class TestClass {
	init() {
    	print("init")
    }
    
    deinit() {
		print("deinit")
    }
}

var testClass: TestClass? = TestClass()
testClass = nil

자 이렇게 그림을 보면 testClass는 TestClass의 객체에 강한 참조를 가지고 있습니다.
하지만 우리가 testClass = nil 이렇게 nil을 할당하면 강한 참조는 사라지고 때문에 TestClass 객체의 메모리는 해제됩니다.

순환참조 - RetainCycle

class TestClass {
	var testClass: TestClass? = nil
    
    init() {
    	print("init")
    }
    
    deinit() {
   		print("deinit")
    }
}
var testClass1: TestClass? = TestClass()
var testClass2: TestClass? = TestClass()

testClass1?.testClass = testClass2
testClass2?.testClass = testClass1

이 코드는  이렇게 TestClass가 서로를 강하게 참조하고 있습니다.

자 여기에 nil을 할당하면 deinit이 실행되고 메모리에서 해제될까요?

하지만 이상하게도 deinit도 실행되지않고 메모리에서도 해제가 안되었습니다!

그 이유는 각각의 객체는 강한 참조를 하나씩 잃었지만 내부적으로 한개씩의 강한 참조를 가지고 있기 때문에 객체들의 메모리가 
해제되지 않습니다!
심지어 두 객체에 대한 참조는 코드에서 더이상 존재하지 않습니다.
즉, 이 두 객체의 메모리를 해제하는 방법은 존재하지 않게 되어버려요.

 

이러한 현상을 메모리 누수라고 합니다.
어플리케이션에서 메모리 누수가 몇군데 발생하면 사용할 때마다 메모리 사용량이 증가하고, 사용량이 늘어나면 iOS는 앱을 kill한다.
따라서 우리는 순환참조을 잘 다뤄야합니다.

마무리

이번 글에서는 Swift의 순환참조에 대해 알아보았다.
다음 글에서는 이러한 현상을 예방하는 법으로 돌아오겠습니다!