Swift는 메모리 관리를 위해 ARC를 사용합니다. ARC는 클래스의 인스턴스가 더 이상 필요하지 않을 때 자동으로 메모리에서 해제합니다.
ARC의 기본 원리는 다음과 같습니다:
https://developer.apple.com/documentation/corefoundation/1521288-cfgetretaincount

공식 문서에 따르면, ‘Core Foundation의 객체의 참조 횟수를 반환한다’고 합니다. 일반적으로 사용하지 않으나, 메모리 누수(Memory leak)를 디버깅할 때 유용하다고 하네요.

메서드의 인자로 받는 타입인 CFTypeRef는 무엇인가 살펴보니, AnyObject 였습니다. AnyObject는 Swift의 모든 클래스들이 따르는 프로토콜을 의미합니다.
import Foundation
class MyClass {
var name: String
init(name: String) {
self.name = name
print("\(name) 객체가 생성되었습니다.")
}
deinit {
print("\(name) 객체가 해제되었습니다.")
}
}
// 테스트 코드
func testRetainCount() {
let obj1 = MyClass(name: "객체1")
print("obj1 생성 후 \(CFGetRetainCount(obj1))")
// 새로운 스코프에서 강한 참조 생성
do {
var obj2: MyClass? = obj1
print("obj2 = obj1 할당 후 \(CFGetRetainCount(obj2))")
}
print("obj2 스코프 종료 후 \(CFGetRetainCount(obj1))")
// 약한 참조 테스트
weak var weakObj = obj1
print("weak 참조 추가 후 \(CFGetRetainCount(obj1))")
}
testRetainCount()
/*
객체1 객체가 생성되었습니다.
obj1 생성 후: 참조 카운트 = 2
obj2 = obj1 할당 후: 참조 카운트 = 3
obj2 스코프 종료 후: 참조 카운트 = 2
weak 참조 추가 후: 참조 카운트 = 2
객체1 객체가 해제되었습니다.
*/
객체를 생성 했을 때 참조 횟수가 2인 것은 CFGetRetainCount를 호출하면, 참조 횟수를 위한 참조로 인해 참조 횟수가 1 증가하는 것으로 추측됩니다.
구조체는 어떨까요?
struct MyStruct {
var name: String
init(name: String) {
self.name = name
print("\(name) 객체가 생성되었습니다.")
}
}
let obj = MyStruct(name: "구조체1")
print("구조체1 생성 후: 참조 카운트 \(CFGetRetainCount(obj))") // Argument type 'MyStruct' expected to be an instance of a class or class-constrained type
CFGetRetainCount의 인자는 CFTypeRef(=AnyObject) 타입 즉, 클래스 이어야 하기 때문에 컴파일 오류가 발생하게 됩니다.