오늘은 함수 인자로 class의 인스턴스를 전달했을 때 ARC의 카운트가 증가하고 함수가 끝나면 카운트가 감소하는지에 대해서 직접 알아보도록 하겠습니다.
ARC는 참조 객체가 사용되면 자동으로 RC를 증가 시키고, 사용이 끝나면 자동으로 RC를 감소시켜줘서 RC가 0이 되었을 때 메모리에서 해제시켜 메모리 누수를 방지해주는 역할을 하고있습니다.
그런데 문득 함수의 인자로 class의 인스턴스를 넘겨주면 그 때 ARC의 카운트가 증가하는지, 그렇다면 함수가 끝나면 카운트가 자동으로 감소하는지 알아보고싶어져서 테스트를 해보았습니다.
먼저 테스트하기위해 아래와같이 코드를 작성해주었습니다.
test를 생성해준 뒤 useTest()에 생성한 test를 넘겨주는 코드입니다. 이때 useTest에서 ARC 카운트의 변화가 있을까? 이것이 오늘 찾아보려고한 부분입니다.
class Test: NSObject {
let name: String
init(name: String) {
self.name = name
print("Test \(name) 생성됨")
}
deinit {
print("Test \(name) 소멸됨")
}
}
func useTest(test: Test) {
//break point
let name = test.name
print("Test\(name) 사용")
}
func checkARC() {
print("==Test 시작==")
let test = Test(name: "테스트")
print("RC +1")
//break point
useTest(test: test)
print("함수 호출 완료")
print("==Test 종료==")
}
checkARC()
일단 checkARC()를 실행했을 때 프린트 결과로는 useTest 함수 내부의 카운트 증감을 알 수 없었기 때문에 확인하고싶은 부분에 break point를 걸고 po CFGetRetainCount(test)라는 LLDB 명령어를 사용해서 RC를 직접 확인했습니다. 정확한 카운트 숫자는 생각한것과 다를 수 있지만 RC가 증가하면 +1이 되기 때문에 증감은 확인할 수 있는 명령어입니다.
( po CFGetRetainCount(test) 명령어를 사용하기위해 Test에 NSObject를 상속받도록 해주었습니다. )
확인결과 RC가 증가하지 않았습니다.

하지만 함수의 인자로 인스턴스를 넘겼을 때 함수 안에서 진행되는 생명주기와 인스턴스를 생성한 곳인checkARC()의 test와 다른 생명주기를 가질 것이기 때문에 ARC가 증가하지 않는다면 test는 한쪽에서만 RC가 감소하면 메모리에서 아예 사라지게되어 치명적인 오류가 날 것이라고 생각했습니다. 그래서 이와 관련된 부분을 찾던 중, swift의 컴파일러가 임의로 판단하여 더이상 사용되지 않을 것 같을 때 ARC 카운터를 감소시킬 수도 있다는 글을 보게 되었고, 그 문제를 해결하기위해 withExtendedLifetime(_:_:)를 사용했습니다.
https://developer.apple.com/documentation/swift/withextendedlifetime(_:_:)-4mmpv
withExtendedLifetime(_:_:) | Apple Developer Documentation
Evaluates a closure while ensuring that the given instance is not destroyed before the closure returns.
developer.apple.com
문서를 보시면
Evaluates a closure while ensuring that the given instance is not destroyed before the closure returns.
"주어진 인스턴스가 클로저의 실행이 끝나기 전에 메모리에서 해제되지 않도록 보장하면서, 그 클로저를 실행합니다."
라고 설명되어있습니다. 이 문장에서 "클로저의 실행이 끝나기 전에 메모리에서 해제되지 않도록 보장" 이라는 말은 클로저가 끝나기 전까지 RC를 감소하지않는다는 뜻이고, 그렇다면 컴파일러가 임의로 감소시키는 것을 무시하고 테스트를 할 수 있다는 뜻이됩니다. 그래서 아래와 같이 코드를 수정하고 다시 RC를 확인해보았습니다.
func useTest(test: Test) {
withExtendedLifetime(test) {
//break point
let name = test.name
print("Test\(name) 사용")
}
}

그 결과 위 사진처럼 2에서 3으로 RC가 증가하는것을 확인할 수 있었습니다.
오늘은 함수 인자로 인스턴스를 전달했을 때 RC가 증가하는지 직접 확인해보았습니다. 중간에 생각과 달라서 RC가 증가하지 않는건가? 라고 생각했지만 그건 아닌 것 같다.. 라는 직감을 믿고 더 찾아본 결과 역시 증가하는것이 맞다는 것을 알아내었습니다.
다음번에는 클로저 캡쳐와 관련해서 ARC가 어떻게 작동되는지 알아보도록 하겠습니다.
'iOS' 카테고리의 다른 글
| Swift의 비동기 프로그래밍 (GCD) (0) | 2025.08.20 |
|---|---|
| 클로저 캡쳐가 일어날 때 ARC는 어떻게 변할까? (0) | 2025.08.19 |
| SwiftUI 프로퍼티 래퍼 (3) | 2025.08.14 |
| SwiftData (2) | 2025.08.13 |
| Coordinator 패턴으로 SwiftUI 화면 전환 시키기 (1) | 2025.08.12 |