728x90
|
ARC (Auto Reference Counting)
- 매번 전달할 때 값을 복사해서 전달하는 값 타입(value type)과 달리 참조 타입(Reference Type)은 하나의 인스턴스가 참조를 통해 여러 곳에서 접근하기 때문에 언제 메모리에서 해제되는지 중요
- Swift에서는 메모리 사용을 관리기법인 ARC 사용
- ARC는 값 타입인 class의 인스턴스만 적용
- enum, struct는 value 타입이므로 무관
- Objective-C에서도 사용
ARC vs Garbage Collection
기법 | ARC | Garbage Collection |
Reference Counting 시점 | 컴파일 시 | 프로그램 동작 중 (런타임 시) |
장점 | - 컴파일 시 메모리 해제 시점이 정해져 있어서 언제 해제 될지 예측 가능 - 해제 시점이 정해져 있어서 메모리 관리를 위한 추가 시스템 자원 필요 x |
- 상호 참조 (Mutual Reference) 등의 상황에서도 인스턴스를 해제할 수 있는 가능성이 더 높음 - 규칙 신경 쓸 필요 없음 |
단점 | - ARC 작동 규칙을 모르면 영원히 인스턴스가 메모리 해제되지 않을 수 있음 | - 프로그램 동작 외에 메모리 관리를 위한 추가 시스템 자원 필요 - 메모리 해제 시점 예측 어려움 |
강한 참조 (Strong Reference)
- 특정 instance를 다른 instance의 프로퍼티, 변수, 상수 등에 할당할 때 강한 참조를 사용하면 참조 횟수가 1 증가
- 강한 참조를 사용 중인 프로퍼티, 변수, 상수에 nil 할당 시 참조 횟수 1 감소
- 인스턴스가 계속해서 메모리에 남아있게 함
- 참조 횟수가 0이 되는 순간 메모리에서 해제됨
- default 참조 방식
import Foundation
class Human {
var name: String
init (_ name: String) {
self.name = name
}
}
var human1: Human? = Human("Park")//참조 횟수 1
var human2: Human? = human1 //참조 횟수 2
var human3: Human? = human2//참조 횟수 3
human1 = nil //참조 횟수 2
human2 = nil //참조 횟수 1
human3 = nil //참조 횟수 0
강한참조 순환 문제 (Strong Reference Cycle)
- 서로가 서로를 강한 참조할 때 발생하는 문제
- delegate 패턴 사용 시, closure 주의해야할 사항
import Foundation
class Human {
var name: String
var pet: Dog?
init (_ name: String) {
self.name = name
}
}
class Dog {
var name: String
var host: Human?
init (_ name: String) {
self.name = name
}
}
var host: Human? = Human("Park")//host 참조 횟수 1
var pet: Dog? = Dog("Happy")//pet 참조 횟수 1
host?.pet = pet //pet 참조 횟수 2
pet?.host = host//host 참조 횟수 2
host = nil //host 참조 횟수 1
pet = nil //pet 참조 횟수 1
//host 인스턴스 참조 불가 - 계속 잔존
//pet 인스턴스 참조 불가 - 계속 잔존
강함참조 순환 문제 해결법
import Foundation
class Human {
var name: String
var pet: Dog?
init (_ name: String) {
self.name = name
}
}
class Dog {
var name: String
var host: Human?
init (_ name: String) {
self.name = name
}
}
var host: Human? = Human("Park")//host 참조 횟수 1
var pet: Dog? = Dog("Happy")//pet 참조 횟수 1
host?.pet = pet //pet 참조 횟수 2
pet?.host = host//host 참조 횟수 2
//수동 해결법
host?.pet = nil//pet 참조 횟수 1
pet?.host = nil//host 참조 횟수 1
host = nil //host 참조 횟수 0
pet = nil //pet 참조 횟수 0
약한 참조 (Weak Reference)
- 강함참조와 달리 자신이 참조하는 인스턴스의 참조횟수를 증가시키지 않는다.
- 프로퍼티, 변수 선언 앞에 weak 키워드 사용
- 약한 참조는 항상 nil이 할당될 수 있어야 하기에 optional 타입의 변수여야 한다.
import Foundation
class Human {
var name: String
weak var pet: Dog?
init (_ name: String) {
self.name = name
}
}
class Dog {
var name: String
weak var host: Human?
init (_ name: String) {
self.name = name
}
}
//weak 사용
var host: Human? = Human("Park")//host 참조 횟수 1
var pet: Dog? = Dog("Happy")//pet 참조 횟수 1
host?.pet = pet //pet 참조 횟수 증가 x
pet?.host = host//host 참조 횟수 증가 x
host = nil //host 참조 횟수 0
pet = nil //pet 참조 횟수 0
미소유참조 (Unowned Reference)
- 약한 참조처럼 참조 횟수를 증가시키지 않는다.
- 약한 참조와는 다르게 참조하는 인스턴스가 항상 메모리에 존재할 것이라는 전제를 기반으로 동작
- 자신이 참조하는 인스턴스가 메모리에서 해제되더라도 nil을 할당해주지 않는다.
- optional이나 변수일 필요 없음
- 미소유참조 중에 메모리에서 해제된 인스턴스에 접근 시도시 런타임 오류 발생
- 따라서 해당 인스턴스가 메모리에서 해제되지 않는다는 확신이 있을 때만 사용
import Foundation
class Human {
var name: String
unowned let pet: Dog
init (_ name: String,_ pet: Dog) {
self.name = name
self.pet = pet
}
}
class Dog {
var name: String
init (_ name: String) {
self.name = name
}
}
var dog: Dog = Dog("Happy")//참조 횟수 1
var human: Human
human = Human("Park", dog) //참조 횟수 증가 x
print(human.pet.name) // Happy
dog = Dog("Sad") //기존 인스턴스 참조 횟수 0
print(human.pet.name) // 런타임 에러 발생
728x90
'Swift' 카테고리의 다른 글
[Swift] 가변매개변수 (Variadic Parameters) (0) | 2021.06.13 |
---|---|
[Swift] class 키워드 vs static 키워드 (0) | 2021.06.02 |
[Swift] where절 (0) | 2021.05.31 |
[Swift] inout 파라미터 (0) | 2021.05.28 |
[Swift] 제네릭 (Generics) (0) | 2021.05.28 |
댓글