안녕하세요~ >< 오늘은 앉아있기 어려운 관계로.. 대부분 쉬어야 겠습니다.. 저녁에 취미로 하는 밴드 합주도 가야하구요 하하

원래는 내일인 금요일에 합주가 예정이었는데 어머니 생신을 토요일로 알고있어서 금요일로 정하였지만, 알고보니 금요일이더군요!! 음력...익숙치않아..(사실 캘린더에 잘못 적음 ㅋ) 하튼 일자목으로 목도 아프고.. 늑연골염?으로 가슴이 매우 아픕니다 ㅋㅋ

운동을 쉬라고 하더군요... 하지만 쉴수 없기에 가슴을 제외한 운동을 진행할것입니다.. 저는... 언제나.. 방법을.. 찾을것입니다...

 

배운점 (자동 참조 카운팅 : Automatic Reference Counting)

Swift는 앱의 메모리 사용량을 추적하고 관리하기 위해 자동 참조 카운팅을 사용합니다!

 

참조 카운팅은 클래스의 인스턴스에만 적용됩니다. 구조체와 열거형은 참조 타입이 아니고 값타입이고 참조로 저장되거나 전달되지 않습니다!!

 

ARC의 작동 원리

클래스의 새로운 인스턴스가 생성될 때마다 ARC는 인스턴스에 대한 정보를 저장하기 위해 메모리의 청크에 할당합니다.
(메모리 청크 : 동적으로 메모리를 할당할 때 사용되는 일정한 크기의 메모리 블록)

이 메모리는 해당 인스턴스와 관련된 저장된 프로퍼티의 값과 함께 인스턴스의 타입에 대한 정보를 가집니다.

또한 인스턴스가 더이상 필요치 않을 때 ARC는 메모리가 다른 목적으로 사용될 수 있도록 인스턴스에 의해 사용된 메모리를 할당 해제합니다. (이렇게 하면 메모리를 효율적으로 관리할 수 있겠군요!)

 

하지만 ARC가 아직 사용중인 인스턴스의 할당을 해제하면 더이상 인스턴스의 프로퍼티에 접근할 수 없거나 인스턴스의 메모리를 호출할 수 없습니다. (인스턴스에 접근하려 하면 앱은 크래시가 발생한다고 합니다.)

 

ARC 동작

class Person {
    let name: String
    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
    }
    deinit {
        print("\(name) is being deinitialized")
    }
}

위의 예제는 ARC의 동작에 대한 예제 입니다.

 

var reference1: Person?
var reference2: Person?
var reference3: Person?

Person에 여러개의 참조를 설정하기 위해 Person? 타입의 3개 변수를 정의합니다. 

옵셔널 타입이므로 nil 값으로 자동으로 초기화되고 현재는 Person 인스턴스를 참조하지 않고 있습니다.

 

reference1 = Person(name: "John Appleseed")
// Prints "John Appleseed is being initialized"

새로운 Person의 인스턴스는 reference1 변수에 할당되기 때문에 강한 참조가 있습니다.

하나의 강한 참조가 있기 때문에 ARC는 이 Person을 메모리에 유지하고 할당 해제하지 않습니다.

 

reference2 = reference1
reference3 = reference1

위의 예제로 이제 Person의 인스턴스에 3개의 강한 참조가 있습니다.

 

reference1 = nil
reference2 = nil

2개의 변수에 nil을 할당하여 강한 참조 3개중 2개가 중단되어 1개의 강한참조만 남고 Person 인스턴스는 할당 해제되지 않습니다.

 

reference3 = nil
// Prints "John Appleseed is being deinitialized"

마지막 강한 참조를 중단하여 Person 인스턴스는 할당 해제 됩니다.

 

 

 

클래스 인스턴스 사이의 강한 참조 사이클

ARC동작의 예제에선 Person 인스턴스를 생성하고 더이상 필요치 않을 때 Person 인스턴스 할당 해제하기 위해 참조의 수를 추적할 수 있습니다.

그러나 클래스의 인스턴스가 강한 참조가 없는 지점에 도달하지 않는 코드를 작성할 수 있습니다. 이는 두 클래스 인스턴스가 서로에 대한 강한 참조를 유지하여 각 인스턴스가 다른 인스턴스를 유지하는 경우 발생할 수 있습니다! 이를 강한 참조 사이클 이라고 합니다.

(예제를 보며 이해를 돕겠습니다~~)

 

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment?
    deinit { print("\(name) is being deinitialized") }
}

class Apartment {
    let unit: String
    init(unit: String) { self.unit = unit }
    var tenant: Person?
    deinit { print("Apartment \(unit) is being deinitialized") }
}

위의 예제에서 Person 인스턴스는 String 타입의 name 프로퍼티와 초기값인 nil 인 옵셔널 apartment 프로퍼티를 가지고 있습니다.

(사람이 항상 아파트를 가지고 있지 않기 때문에 apartment 프로퍼티는 옵셔널 입니다.)

 

Apartment는 Person과 비슷하기 String 타입의 unit 프로퍼티와 초기값이 nil 인 옵셔널 tenant 프로퍼티를 가지고 있습니다.

(아파트를 항상 보유하는 것은 아니므로 tenant 프로퍼티는 옵셔널 입니다. 아파트는 항상 거주자를 보유하지 않으니까 로 이해해도 괜찮은건지...)

 

var john: Person?
var unit4A: Apartment?

옵셔널 타입의 2개의 변수를 정의합니다.

이제 특정 Person 인스턴스와 Apartment 인스턴스를 생성할 수 있습니다.

john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

 

다음은 강한 참조가 이 두 인스턴스를 생성하고 할당하여 어떻게 보이는지 나타냅니다.

john변는 이제 새로운 Person 인스턴스에 대한 강한 참조를 가지고 있고, unit4A는 Apartment 인스턴스에 대해 강한 참조를 가지고 있습니다.

john!.apartment = unit4A
unit4A!.tenant = john

이제 사람은 아파트를 가지고 아파트는 소유자를 가지도록 두 인스턴스를 연결했습니다.
위의 예제로써 강한참조가 밑의 그림처럼 바뀌었습니다.

불행히도? 이 두인스턴스 연결은 강한 참조 싸이클을 생성합니다. 따라서 john과 unit4A변수에 의해 가진 강한 참조를 중단할 때 참조 카운트는 0으로 떨어지지 않고 인스턴스는 ARC에 의해 할당 해제되지 않습니다.

(참조가 발생할경우 ARC에 의해 참조 카운트가 1씩 증가, 참조가 해제되면 1감소)

 

john = nil
unit4A = nil

위의 코드로 nil로 설정할때 초기화 해제 구문은 호출이 되지 않습니다.

강한 참조 사이클은 Person과 Apartment 인스턴스가 할당 해제되는 것을 방지하여 앱에서 메로리 누수를 유발합니다!

따라서 Person과 Apartment 인스턴스 간의 강한 참조는 남아있고 중단 될 수 없습니다.

 

 

클래스 인스턴스 간의 강한 참조 사이클 해결

위와같은 문제를 해결하기 위해 Swift는 2개의 해결방법을 제공합니다.

1. 약한 참조 (weak reference)

2.미소유 참조 ( unowned reference )

 

이 2개를 사용하면 참조 사이클의 한 인스턴스가 강한 유지 없이 다른 인스턴스를 참조할 수 있습니다.

 

약한 참조를 사용하는 경우

다른 인스턴스의 수명이 더 짧은 경우 즉, 다른 인스턴스가 먼저 할당 해제 될 수 있을 때 약한 참조를 사용합니다. 

위의 Apartment 예제에서 아파트는 어느 시점에 소유자가 없을 수 있는 것이 적절하므로 이경우 약한 참조를 사용하여 참조 사이클을 끊는 것이 적절한 경우 입니다.

 

미소유 참조를 사용하는 경우

다른 인스턴스의 수명이 동일하거나 더 긴 경우 미소유 참조를 사용합니다.

 

(오느른 여기까지...)

생각과 감정

건강하자고 한 운동이 잘못된 자세로 인해 건강을 해치고 있었군요... 그리고 컴퓨터를 많이해 일자목이.. 큽...

여러분도 자세 바르게하는 습관을 꼭 유지하세요....

 

요즌 document를 읽으면서 느끼는 감정이 대학 1, 2학년에 새로운 언어를 배울때 느끼는 감정과 조금은 비슷하네요ㅋ..

사실 그때는 이런걸 배우는 이유는 생각하지 않고 그냥 just 배워~ 학점을 위해서 머리에 때려넣고 까먹었는데

지금은 절대.. 절대는 모르겠지만 머리에 계속 남아있게 한번씩 들려서 다시 봐야겠어요.. 그리고 조금은 재밌다랄까요?

언어의 특징을 배우면서 한발짝은 아니어도 조금은 Swift와 친해졌다는 느낌이 많이 듭니다 ㅎㅎ

 

참조를 배우면서 예전에 다른 언어에서 배운것에대한 기본기는 조금? 비슷해서 이해하기 수월했습니다.. 그래도 조금 수월한 것이지 많이 어렵네요 ㅎㅎ

 

앞으로의 계획선언

빨리 회복해서 다음 약한참 조와 미소유 참조를 공부 하도록 하겠습니다!! 
그리고 개인 프로젝트를 준비해야겠어요 마냥 document만 읽고있을수는 없으니 간단한 앱으로 시작하며 성장하겠습니다~~

모두들 화이팅!

 

 

'TIL' 카테고리의 다른 글

TIL_20230921  (0) 2023.09.21
TIL_20230918  (0) 2023.09.18
TIL_20230913  (0) 2023.09.13
TIL_20230912  (0) 2023.09.12
TIL_20230911  (0) 2023.09.11

+ Recent posts