![Swift : 고급문법 [ARC 메모리 관리 3 - 약한참조(weak)] Swift : 고급문법 [ARC 메모리 관리 3 - 약한참조(weak)]](https://blog.kakaocdn.net/dna/bC9Jix/btrtRWhbQ5x/AAAAAAAAAAAAAAAAAAAAANrUxJPEWgx2O4g2jDHL7Gqd-WhoynRZewSqo8n4QhAX/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1756652399&allow_ip=&allow_referer=&signature=633%2FzAw3JkiEfmOv2uMzj%2F71VsQ%3D)
약한 참조
- 강한 참조와 달리 자신이 참조하는 인스턴스의 참조 횟수를 증가시키지 않음
- 참조 타입의 프로퍼티나 변수의 선언 앞에
weak 키워드
를 사용하면 그 프로퍼티나 변수는 자신이 참조하는 인스턴스를 약한 참조함 - 약한 참조를 사용하면 자신이 참조하는 인스턴스가 메모리에서 해제될 수 도 있다는 것을 예상할 수 있음
- 참조하는 인스턴스에 대한 참조를 강하게 유지하지 않기 때문에 약한 참조로 참조되고 있는 동안에도 해당 인스턴스가 할당 해제될 수 있음
ARC
는 인스턴스가 할당 해제될 때 해당 인스턴스를 약한 참조하는 프로퍼티를nil
로 초기화함- 때문에 약한 참조는 항상 옵셔널 변수에만 사용 가능하며, 약한 참조는 상수에서 쓰일 수 없음
약한 참조와 상수, 옵셔널
만약 자신이 참조하던 인스턴스가 메모리 해제되면 nil
이 할당될 수 있어야 하기 때문에 약한 참조는 상수에서 쓰일 수 없다. 그래서 약한 참조를 할 땐 자신의 값을 변경할 수 있는 변수로 선언해야 한다. 또, nil
이 할당될 수 있어야 하므로 약한참조는 당연히 항상 옵셔널
이여야 한다. 즉, 옵셔널 변수에만 약한참조
를 할 수 있다.
강한 참조 순환에서 사용했던 코드
강한 참조 순환에서 사용했던 Room
클래스에서 host
프로퍼티를 약한 참조로 바꿔보면 다음과 같다.
class Person { let name: String init(name: String) { self.name = name } var room: Room? deinit { print("\(name) is being deinitialized!") } } class Room { let number: String init(number: String) { self.number = number } //var host: Person? weak var host: Person? deinit { print("Room \(number) is being deinitialized!") } }
그리고 seogun
과 myRoom
의 관계는 이러했다.
var seogun: Person? = Person(name: "서근") // Person 인스턴스의 참조 횟수 : 1 var myRoom: Room? = Room(number: "50") // Room 인스턴스의 참조 횟수 : 1 seogun?.room = myRoom // Room 인스턴스의 참조 횟수 : 2 myRoom?.host = seogun // Person 인스턴스의 참조 횟수 : 1 (약한 참조니까!!!!)
![Swift : 고급문법 [ARC 메모리 관리 3 - 약한참조(weak)] - 약한 참조 Swift : 고급문법 [ARC 메모리 관리 3 - 약한참조(weak)] - 약한 참조](https://blog.kakaocdn.net/dna/b9D8WX/btrtRXtDRDx/AAAAAAAAAAAAAAAAAAAAAKJyBpLzVmHoOPPjCLKic7ZofF_uYEx4sgG2lGBx6Qea/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1756652399&allow_ip=&allow_referer=&signature=HXnNsu8n%2BqC0m%2BlnLaCnLtQ703o%3D)
Person
인스턴스는 Room
인스턴스에 대에 강한 참조를 여전히 유지하고 있는데 반해, Room
인스턴스는 Person
인스턴스에 대해 약한 참조를 가지게 됐다.
이는 seogun
변수에 nil
을 할당해 Person
인스턴스에 대한 강한 참조를 해제하게 된다면, Person
인스턴스는 더 이상 강한 참조를 갖지 않게 된다.
그러니까 Person
과 Room
클래스는 둘 다 강한 참조이고, myRoom
변수가 Room
인스턴스에 강한 참조 했고, 이것을 Person
인스턴스에 약한 참조로 전달했으니(참조 횟수 증가 안 함) Person
인스턴스는 var seogun
변수를 제외한 모든 인스턴스가 약한 참조인 것!
여기서 유일한 강한 참조인 var seogun
에 nil
을 주면?
![Swift : 고급문법 [ARC 메모리 관리 3 - 약한참조(weak)] - 약한 참조 Swift : 고급문법 [ARC 메모리 관리 3 - 약한참조(weak)] - 약한 참조](https://blog.kakaocdn.net/dna/zGTlC/btrtTLsXtIo/AAAAAAAAAAAAAAAAAAAAAOiwHh4IZ7LVTdgr9IVvZjXBgShIgPgKQv4XQXuuv0dB/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1756652399&allow_ip=&allow_referer=&signature=H0PHHxz90PVJ4RJhRn%2Fu%2Bg9IVNI%3D)
더 이상 Person
인스턴스에 대한 강한 참조가 존재하지 않으므로, Person
인스턴스가 할당 해제 되었고, Person
인스턴스에 대해 약한 참조를 가지고 있던 host
프로퍼티는 nil
이 된다.
print(myRoom?.host) //옵셔널 Person seogun = nil // Person 인스턴스 참조 횟수 : 0 , Room 인스턴스의 참조 횟수 : 1 //서근 is being deinitialized! print(myRoom?.host) //nil
왜 host
가 nil
이냐? Person
이 존재 하지 않으니까!
weak var host: Person? //Person이 존재하지 않으니까 host도 nil
이렇게 Room
인스턴스에 대한 강한 참조는 myRoom
변수가 가지는 강한 참조만 남게 된다. 이 강한 참조 마저 해제해 버린다면? Room
인스턴스는 더 이상 강한 참조를 가지지 않게 되면서 디이니셜라이저를 호출한다.
myRoom = nil // Room 인스턴스의 참조 횟수 : 0 //Room 50 is being deinitialized!
전체적인 코드를 보면 이러하다.
class Person { let name: String init(name: String) { self.name = name } var room: Room? deinit { print("\(name) is being deinitialized!") } } class Room { let number: String init(number: String) { self.number = number } weak var host: Person? deinit { print("Room \(number) is being deinitialized!") } } var seogun: Person? = Person(name: "서근") // Person 인스턴스의 참조 횟수 : 1 var myRoom: Room? = Room(number: "50") // Room 인스턴스의 참조 횟수 : 1 seogun?.room = myRoom // Room 인스턴스의 참조 횟수 : 2 myRoom?.host = seogun // Person 인스턴스의 참조 횟수 : 1 (약한 참조니까!!!!) print(myRoom?.host) //옵셔널 Person seogun = nil // Person 인스턴스의 참조 횟수 : 0 , Room 인스턴스의 참조 횟수 : 1 //서근 is being deinitialized! print(myRoom?.host) //nil myRoom = nil // Room 인스턴스의 참조 횟수 : 0 //Room 50 is being deinitialized!
다음 게시글은 미소유 참조에 대해 알아보도록 하겠습니다.
읽어주셔서 감사합니다 🤟
'SWIFT > Grammar' 카테고리의 다른 글
Swift 기초 문법 모음 (9) | 2022.02.24 |
---|---|
Swift : 고급문법[ARC 메모리 관리4 - 미소유 참조(unowned)] (0) | 2022.02.19 |
Swift : 고급문법 [ARC 메모리 관리 2 - 강한 참조 순환 문제] (0) | 2022.02.12 |
Swift : 고급문법 [ARC 메모리 관리 1 - 강한 참조] (0) | 2022.02.10 |
Swift: 기초문법 [데이터 타입 - Int와 UInt (feat.카멜케이스)] (4) | 2022.02.09 |