Closed Glsme closed 1 year ago
keyword
Auto Reference Counting
꼬리 질문
앱의 메모리 사용량을 추적하고 관리 -> class, closure와 같은 참조형 자료들이 머무는 공간인 Heap 영역, 개발자가 동적으로 할당하는 메모리 공간이기 때문에 관리가 필요함!
해당 인스턴스가 더 이상 필요하지 않을 때 클래스 인스턴스에서 사용하는 메모리를 자동으로 해제. 메모리 릭 현상을 자동으로 막아줌.
weak, unowned 키워드를 사용해서 메모리 누수 방지 가능
컴파일 시점에 적절한 위치에 'retain', 'release' 코드 삽입 -> reference count가 0이 되면 deinit
Objc-C : MRC(Manual Reference Counting)로 수동으로 관리 = 참조한 갯수를 세어주기, 참조당한 레퍼런스를 +1, nil이 되면 -1
클래스의 새로운 인스턴스를 생성하면 ARC는 해당 인스턴스에 대한 정보를 저장하기 위해 메모리 청크를 할당. 메모리에서는 인스턴스의 타입과 해당 인스턴스와 관련된 저장 프로퍼티 값을 함께 저장.
인스턴스가 더 이상 필요하지 않으면 ARC는 메모리를 해제해서 다른 목적으로 사용할 수 있게 함.
하지만 사용중인 인스턴스를 ARC가 메모리할당을 취소할 경우, 더 이상 인스턴스 프로퍼티 접근과 메서드 호출이 불가. 그 인스턴스에 접근하려고 하면 앱이 크래시가 됨.
인스턴스가 사용중일 때 사라지지 않도록 ARC는 프로퍼티, 상수, 변수가 각 클래스 인스턴스에 참조되는 갯수를 트랙킹. ARC는 인스턴스에 액티브 레퍼런스가 하나로도 있으면 메모리를 해제하지 않음.
4
가 가능하기 위해 프로퍼티, 상수, 변수에 클래스 인스턴스를 할당할 때마다 인스턴스에 대한 strong
참조를 만듬. 이 strong 참조가 남아있는 한 메모리 해제를 허용하지 않음.
두개의 클래스가 서로를 strong 하게 참조할 경우 참조 카운팅이 0이 될 수 없다. 이러한 참조 사이클 문제는 해당 클래스간의 관계를 weak
, unowned
로 정의하여 해결할 수 있다.
weak
프로퍼티나 변수 정의 앞에 weak
키워드를 붙여 정의.
약한 참조는 런타임 시 값이 nil로 변경될 수 있도록 허용해야 하므로, 상수가 아니라 옵셔널 변수 타입으로 선언되어야 한다.
unowned
weak
와 다르게 unowned
참조는 다른 인스턴스가 동일하거나 더 긴 수명을 가졌을 때 사용한다. 또한 weak
참조와 다르게 항상 값을 가진다. 즉 ARC가 nil로 참조를 설정하지 않으므로 옵셔널로 선언하지 않다.
즉, unowned 참조는 메모리에서 해제되지 않는 인스턴스를 참조해야한다는 점. 만약 메모리가 해제된다면 런타임 에러를 만나게 될 것.
강한 참조 사이클은 클래스 인스턴스 프로퍼티에 클로저를 할당하고, 클로저의 바디가 인스턴스를 캡쳐할 때 발생할 수 있음.
예를 들어 self.someProperty
에 접근하거나 또는 인스턴스의 메서드를 호출 self.someMethod()
하거나. 이 경우 클로저가 self
를 캡쳐하여 강한 참조 사이클을 만든다.
이런 강함 참조 사이클이 발생하는 이유는 클로저가 클랫스처럼 참조 타입이기 때문. 프로퍼티에 클로저를 할당하면, 해당 클로저에 참조를 할당하는 것.
이를 해결하기 위한 것이 클로저의 캡쳐리스트.
** btw. 클로저가 self
를 여러 번 참조하더라도, 해당 인스턴스의 대한 강력한 참조는 단 한 번만 캡쳐한다.
캡처리스트를 클로저 정의할 때 정의. 캡쳐리스트는 클로저 바디에서 하나 이상의 참조 타입을 캡쳐할 때 사용되는 규칙을 정의한 것.
lazy var exampleClosure = {
[unowned self, weak delegate = self.delegate]
(index: Int, Value: String) -> String in
// 클로저 바디
}
ARC (Auto Reference Counting)
2022.12.28 (수) 모임 전까지 작성해주세요.