Strong 참조 (Strong Reference)
기본적으로 모든 참조는 강한 참조이다. 강한 참조는 참조하는 인스턴스의 생명주기를 유지한다. 즉, 강한 참조가 있는 한, 해당 인스턴스는 메모리에서 해제되지 않는다.
class Person {
var name: String
init(name: String) {
self.name = name
}
}
var person1: Person? = Person(name: "Alice")
var person2 = person1 // person1을 강한 참조
person1 = nil // person1이 nil이 되어도 person2가 참조하고 있으므로 메모리에서 해제되지 않음
person2 = nil // 모든 강한 참조가 해제되면 메모리에서 해제됨
Weak 참조 (Weak Reference)
약한 참조는 강한 참조 사이클을 피하기 위해 사용된다. 약한 참조는 참조하고 있는 인스턴스의 생명주기에 영향을 미치지 않는다. 약한 참조는 옵셔널로 선언되어야 하며, 참조하고 있는 인스턴스가 해제되면 nil이 된다.
class Person {
var name: String
var dog: Dog?
init(name: String) {
self.name = name
}
}
class Dog {
weak var owner: Person?
deinit {
print("Dog 인스턴스가 해제됨")
}
}
var person: Person? = Person(name: "Alice")
var dog: Dog? = Dog()
person?.dog = dog
dog?.owner = person // 약한 참조를 사용하여 순환 참조를 피함
person = nil // person 인스턴스가 해제됨
// dog.owner는 nil이 됨
dog = nil // dog 인스턴스가 해제됨
Unowned 참조 (Unowned Reference)
비소유 참조는 약한 참조와 비슷하지만, 참조하고 있는 인스턴스가 항상 존재한다고 가정한다. 따라서 비옵셔널로 선언된다. 인스턴스가 해제된 후 비소유 참조를 사용하려고 하면 런타임 에러가 발생한다. 주로 참조 대상이 자신보다 오래 살아있을 때 사용한다.
class Person {
var name: String
var creditCard: CreditCard?
init(name: String) {
self.name = name
}
}
class CreditCard {
var number: Int
unowned let owner: Person
init(number: Int, owner: Person) {
self.number = number
self.owner = owner
}
deinit {
print("CreditCard 인스턴스가 해제됨")
}
}
var person: Person? = Person(name: "Alice")
person?.creditCard = CreditCard(number: 1234, owner: person!)
person = nil // person 인스턴스가 해제되면서 creditCard도 해제됨
// 비소유 참조는 런타임 에러를 방지하기 위해 항상 참조 대상이 존재할 것을 보장해야 함
요약
- Strong 참조: 기본 참조 방식으로, 참조하는 인스턴스의 생명주기를 유지한다.
- Weak 참조: 순환 참조를 피하기 위해 사용되며, 참조하고 있는 인스턴스가 해제되면 nil이 됩니다. 옵셔널로 선언해야 한다.
- Unowned 참조: 참조 대상이 항상 존재한다고 가정하며, 비옵셔널로 선언된다. 참조 대상이 해제된 후 접근하면 런타임 에러가 발생한다.
https://bbiguduk.gitbook.io/swift/language-guide-1/automatic-reference-counting#unowned-references