금, 토, 일요일을 신나게 쉬었습니다.. 하하 금요일은 어머니 생신을 같이 보냈구요, 토요일은 여자친구와 함께 시간을 보냈습니다~ 
일요일은 늑연골염 덕분에 거의 누워있었던것 같습니다...

이정도면 많이 쉬었군요. 어제 장수상회를 보며 눈물을 질질 흘렸습니다.. 얼마나 슬프던지 배우분들을 보면서 할머니랑 할아버지 생각이 나 눈물이 더 많이 났던것 같네요.. 여러분들도 한번쯤은 보면 좋은 영화입니다 가족애 뿜뿜 ㅎㅎ 

흐 계속 쉬고싶지만.. 누워만 있는건 조금 찔리는것 같네요 하하하...흐...ㅎ...ㅡ....ㅠㅠ,,,,

 

배운점

저번에 다하지 못한 미소유 참조 와 약한참조를 공부해보겠습니다!

 

약한 참조

약한 참조는 참조하는 인스턴스를 강하게 유지하지 않는 참조이므로 ARC가 참조된 인스턴스를 처리하는것을 중지하지 않는다고 합니다.

이 동적운 참조가 강한 참조 사이클의 일부가 되는 것을 방지합니다!

프로퍼티나 변수의 선언 앞에 weak 키워드를 위치시켜 약한참조를 나타냅니다.

 

약한 참조는 참조하는 인스턴스를 강하게 유지하지 않기 때문에 약한 참조가 참조하는 동안 인스턴스가 할당 해제 될 수 있습니다!

따라서 ARC는 인스턴스가 해제되면 nil 로 약한 참조를 자동으로 설정합니다.

따라서 nil 로 바뀌는 것을 허락 해야하므로 옵셔널 타입의 변수로 선언됩니다.

 

다른 옵셔널 값과 같이 약한 참조에 값의 존재를 확인할 수 있고, 더이상 존재하지 않는 유효하지 않은 인스턴스에 참조하는것으로 끝나지 않습니다 (????) -> 약한 참조는 옵셔널 값과 유사하지만, 옵셔널 값처럼 유효하지 않은 인스턴스를 참조할수 없다는 것을 의미하는것 같네요..

 

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 }
    weak var tenant: Person?
    deinit { print("Apartment \(unit) is being deinitialized") }
}

위의 코드는 Apartment 클래스의 tenant 프로퍼티는 약한참조로 선언되었습니다.

var john: Person?
var unit4A: Apartment?

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

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

이전과 같이 john과 ubut4A는 강한참조로 연결됩니다.

Person 인스턴스는 Apartment 인스턴스에 대해 강한 참조를 가지고 있지만 Apartment 인스턴스는 Person 인스턴스에 대해 약한참조를 가지고 있습니다. -> john 변수에 nil 을 할당하여 강한참조를 끊으면 Person 인스턴스에 대해 더이상 강한참조가 아님을 의미합니다.

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

더이상 Person 인스턴스에 대해 강한 참조를 가지고 있지 않기 때문에 할당 해제되고 tanant 프로퍼티는 nil 이 됩니다.

Apartment 인스턴스에 대한 유일한 참조는 unit4A 변수에서 가져온 것입니다. 강한참조를 끊으면 Apartment 인스턴스에 대한 강한참조는 더이상 없습니다.

unit4A = nil
// Prints "Apartment 4A is being deinitialized"

Apartment에 대한 강한참조가 없으니 할당 해제 됩니다.

 

 

미소유 참조

미소유 참조는 약한 참조와 같이 인스턴스를 강하게 유지하지 않습니다. 하지만 약한 참조와 다르게 미소유 참조는 다른 인스턴스의 수명이 같거나 더 긴 경우에 사용됩니다.

프로퍼티 선언 앞부분에 unowned 키워드를 붙여 미소유 참조를 나타냅니다.

 

약한 참조와 달리 미소유 참조는 항상 값을 갖도록 예상됩니다. 따라서 미소유로 만들어진 값은 옵셔널이 아니고, ARC는 미소유 참조의 값을 nil로 할당하지 않습니다.

 

class Customer {
    let name: String
    var card: CreditCard?
    init(name: String) {
        self.name = name
    }
    deinit { print("\(name) is being deinitialized") }
}

class CreditCard {
    let number: UInt64
    unowned let customer: Customer
    init(number: UInt64, customer: Customer) {
        self.number = number
        self.customer = customer
    }
    deinit { print("Card #\(number) is being deinitialized") }
}

위의 예제는 Customer 와 CreditCard의 관계입니다. 고객은 신용카드를 가지고 있거나 아닐수 있지만, 신용카드는 항상 고객과 연관되어 있습니다.

신용카드의 인스턴스는 참조하는 고객보다 오래 지속되지 않습니다. -> 고객 클레스는 옵셔널 card를 가지지만, 신용카드 클래스는 미소유와 옵셔널이 아닌 customer 프로퍼티를 가집니다.

신용카드는 항상 고객을 가지고 있으므로 강한 참조 사이클을 피하기 위해 customer 프로퍼티에 미소유 참조로 정의합니다.

 

var john: Customer?

john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)

john에 Customer 인스턴스를 할당하고, card프로퍼티에 CreditCard 인스턴스를 할당합니다.

Customer 인스턴스는 CreditCard 인스턴스에 강한 참조를 가지고 있고, CreditCard 인스턴스는 customer에 대해 미소유 참조를 가지고 있습니다.

 

john변수에 의해 강한 참조를 끊을때 미소유 customer 참조 때문에 Customer 인스턴스에 대해 더이상 강한 참조를 가지지 않습니다.

john = nil
// Prints "John Appleseed is being deinitialized"
// Prints "Card #1234567890123456 is being deinitialized"

john에 nil을 설정하면 Customer과 CreditCard 인스턴스 모두 초기화 해제 됩니다.

 

(이해를 위한 덧붙임)

- 은행 고객 A가 신용카드 B를 가지고 있습니다.

Customer 클래스의 인스턴스 A가 생성됩니다.

CreditCard 클래스의 인스턴스 B가 생성됩니다.

A의 card 프로퍼티에 B를 할당합니다.

B의 customer 프로퍼티에 A를 할당합니다.

 

- 은행 고객 A가 신용카드 B를 해지 합니다.

A의 card 프로퍼티에서 B를 삭제합니다.

B의 customer 프로퍼티에서 A를 삭제합니다.

A의 인스턴스가 해제됩니다.

B의 인스턴스가 해제됩니다.

 

 

생각과 감정

한번 읽어서는 이해가 안되는 부분이 너무 많군요.. 미소유참조 약한참조 둘다 두번이상은 읽은것 같습니다... 

이해가 빠릿빠릿 하게 되었으면 하네요..ㅠㅠ

조금씩 정진합시다 정진!

 

앞으로의 계획선언

내일부터는 졸업을 위한 OPIC공부와 정보처리기사 준비를 같이 해야할것 같네요!! 문서는 짬나거나 궁금한것이 있을때

다시한번 보는걸로 하고,,,, 앱개발 인강을 들으며 내실을 쌓아야 하겠습니다!!

 

'TIL' 카테고리의 다른 글

TIL_20231006  (0) 2023.10.06
TIL_20230921  (0) 2023.09.21
TIL_20230914  (0) 2023.09.14
TIL_20230913  (0) 2023.09.13
TIL_20230912  (0) 2023.09.12

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

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

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

 

배운점 (자동 참조 카운팅 : 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