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
- wil
- tableview section별 다른 cell적용
- 롤케이크 자르기
- ReferceCycle
- 면접을 위한 CS 전공 지식 노트 Tree
- CarouselCollectionview
- SWIFT
- retain cycle
- UserDefaults
- 양궁대회
- til
- @escaping
- TableView Section
- 면접을 위한 CS전공 지식 노트
- UIKit
- TableView
- 프로그래머스
- Carousel CollectionView
- 자료구조
- CoreData
- firebase
- Input Output
- 강한 참조 순환
- coremotion
- Array vs Linked List
- Reference Cycle
- class struct
- NavigationSearchBar
- Value Type Reference Type
- 테이블뷰 나누기
Archives
- Today
- Total
개발하는 동글 :]
[TIL],[Swift],[Closure 강한 참조 순환] 본문
1. 클로저의 강한 참조 순환은 왜 발생할까?
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
print("\(name) is being deinitialized")
}
}
해당 클래스는 name과 text, lazy asHTML 속성을 가지고 있다.
그리고 asHTML속성을 살펴보면 text에 따라 값을 반환하는 함수이다.
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
paragraph = nil
//print("\(name) is being deinitialized")
여기서 먼저 이러한 코드를 통해 paragraph를 nil로 할당해 주면
정상적으로 메모리에서 해제된 것을 확인할 수 있다.
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
print(paragraph!.asHTML())
// Prints "<p>hello, world</p>"
paragraph = nil
하지만 lazy 속성을 사용한 후 nil을 할당하면 메모리에서 해제되지 않는 것을 확인할 수 있다.
왜 이런 일이 일어나는 걸까?
이미지에 나와있듯이 asHTML 내부의 text와 name이 해당 인스턴스를 강하게 참조하고 해당 인스턴스 또 한 함수를 강하게 참조하기 때문이다.
2. 클로저의 강한 참조 순환 해결
lazy var asHTML: () -> String = { [weak self] in
if let text = self?.text {
return "<\(self?.name)>\(text)</\(self?.name)>"
} else {
return "<\(self?.name) />"
}
}
캡처될 항목을 사전에 weak나 unowned 키워드를 붙여서 정의해 준다면 실수로 캡처를 할 수 있는 상황을 방지할 수 있다.
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
print(paragraph!.asHTML())
//<Optional("p")>hello, world</Optional("p")>
paragraph = nil
//p is being deinitialized
정상적으로 메모리에서 해제됨