Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- Protocol
- Clean Code
- uitableview
- RxCocoa
- UICollectionView
- 리펙터링
- combine
- Human interface guide
- Refactoring
- MVVM
- swift documentation
- ios
- tableView
- rxswift
- map
- Xcode
- 스위프트
- uiscrollview
- UITextView
- collectionview
- 애니메이션
- 리팩토링
- 리펙토링
- clean architecture
- 클린 코드
- SWIFT
- swiftUI
- Observable
- ribs
- HIG
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] (reference count) 참조 카운트의 정확한 이해 (weak var, retain cycle, ARC) 본문
iOS 기본 (swift)
[iOS - swift] (reference count) 참조 카운트의 정확한 이해 (weak var, retain cycle, ARC)
jake-kim 2021. 9. 8. 00:17ARC의 기본 개념
참조 카운트 확인 방법
- CGFGetRetainCount(object)를 사용하여 확인
// ex)
print(CFGetRetainCount(obejct1)) // 2
print(CFGetRetainCount(obejct1.property1)) // 2
print(CFGetRetainCount(obejct2)) // 2
obejct1.property1 = object2
print(CFGetRetainCount(obejct1)) // 2
print(CFGetRetainCount(obejct1.property1)) // 3
print(CFGetRetainCount(obejct2)) // 3
참조 카운트가 증가하는 구체적인 상황
- 참초 가운트 테스트를 위한 클래스 정의
protocol AnimalDelegate {
func update()
}
class Person {
var name: String
var animal: Animal
init(name: String, animal: Animal) {
self.name = name
self.animal = animal
}
}
extension Person: AnimalDelegate {
func update() {
print("update")
}
}
class Animal {
var delegate: AnimalDelegate?
var name: String
init(name: String) {
self.name = name
}
}
- 카운트가 증가하는 경우
normalAnimal.delegate = normalPerson // normalPerson 값 +1
normalAnimal = normalPerson.animal // normalPerson은 변화 없지만, normalPerson.animal 값 +1
- 주의
- 1) 클래스에서 property를 접근할때, 해당 property도 참조당한 것이므로 +1
- 2) 전체 객체가 오르지 않고 객체 내 다른 객체를 참조한 부분만 참조 카운트 +1
// normalPerson.animal 값 +1
// 1) normalAnimal 값 +1
// 2) normalPerson의 값은 유지
normalPerson.animal = normalAnimal
- 카운트가 증가할것 같지만 증가하지 않는 경우
// 케이스1
/// normalAnimal 값 +1, normalPerson.animal 값 +1 (단, normalPerson이 아닌 animal값이 +1되는것을 주의)
normalPerson.animal = normalAnimal
/// normalPerson.animal의 값이 변하지 않고 유지되는 것을 주의 (위에서 이미 normalPerson에 의해 참조된 상태이므로)
normalAnimal = normalPerson.animal
//~~//
// 케이스2
/// normalPerson.animal의 값 +1 (normalAnimal이 참조해서 그런게 아닌, normalPerson이 참조하여 +1)
normalAnimal = normalPerson.animal
- delegate를 weak var로 할 경우 참조 카운트 올라가지 않기때문에 retain cycle 방지
- normalAnimal.delegate에서 delegate에 접근했으므로, `normalAnimal.delegate`의 값 +1
- normalPerson은 delegate에게 참조를 당했지만 weak인 상태이므로 normalPerson의 값은 유지
- weak delegate가 아닌 경우, Animal 클래스 내부의 프로퍼티와 normalPerson가 서로 참조하는 상황 (retain cycle)
class Animal {
weak var delegate: AnimalDelegate?
...
}
normalAnimal.delegate = normalPerson // normalPerson 값 유지
- 전체 코드
protocol AnimalDelegate: AnyObject {
func update()
}
class Person {
var name: String
var animal: Animal
init(name: String, animal: Animal) {
self.name = name
self.animal = animal
}
}
extension Person: AnimalDelegate {
func update() {
print("update")
}
}
class Animal {
var delegate: AnimalDelegate?
var name: String
init(name: String) {
self.name = name
}
}
var normalPerson = Person(name: "jake", animal: Animal(name: "jake-"))
var normalAnimal = Animal(name: "강아지")
print(CFGetRetainCount(normalPerson))
normalPerson.animal = normalAnimal // normalAnimal 값 +1
print(CFGetRetainCount(normalPerson))
print(CFGetRetainCount(normalPerson.animal))
normalAnimal = normalPerson.animal // normalPerson은 변화 없지만, normalPerson.animal 값 +1
print(CFGetRetainCount(normalPerson.animal))
'iOS 기본 (swift)' 카테고리의 다른 글
Comments