티스토리 뷰

Auto Reference Counting - Part 4

( a.k.a ARC )

 

 

 

Swift 5.0 - The Swift Programming Language (Apple Inc.)  번역 

(고새 5.0이 되버렸네요..)

 

 

ARC 1편 - ARC 의 개요와 작동 원리 (https://atelier-chez-moi.tistory.com/37)

ARC 2편 - 강한 순환 참조 (https://atelier-chez-moi.tistory.com/40)

ARC 3편 - 강한 순환 참조 해결하기(1) : 약한 참조 (https://atelier-chez-moi.tistory.com/41)

ARC 4편 - 강한 순환 참조 해결하기(2) : 미소유 참조 (현재 글)

 

Unowned References

미소유 참조

 

Like a weak reference, an unowned reference does not keep a strong hold on the instance it refers to. 

Unlike a weak reference, however, an unowned reference is used when the other instance has the same lifetime or a longer lifetime. 

You indicate an unowned reference by placing the unowned keyword before a property or variable declaration.

 

약한 참조와 같이, 미소유 참조 는 참조하고 있는 인스턴스를 강하게 붙잡는 상태를 유지하지 않습니다. 

그러나 약한 참조와는 달리 미소유 참조는 다른 인스턴스가 동일하거나 그 긴 수명을 가질 때에 사용됩니다.

(약한 참조는 짧은 수명을 가질 때 사용되었었죠?)

우리는 미소유 참조를 'unowned' 키워드를 프로퍼티 혹은 변수 선언 전에 위치시킴으로서 나타낼 수 있습니다.

(unowned var x = Person? 처럼요)


An unowned reference is expected to always have a value. 

As a result, ARC never sets an unowned reference’s value to nil

which means that unowned references are defined using non-optional types.

 

미소유 참조는 항상 값을 가지고 있는 것으로 예상됩니다. 결과적으로, ARC 는 미소유 참조의 값을 nil 로 설정하지 않는데, 

이것은 미소유참조가 옵셔널이 아닌(non-optional) 타입을 사용하여 정의된다는 것을 의미합니다.

 

 

IMPORTANT

Use an unowned reference only when you are sure that the reference always refers to an instance that has not been deallocated.
If you try to access the value of an unowned reference after that instance has been deallocated, you’ll get a runtime error.

 

미소유 참조는 오직 참조가 항상 할당 해제되지 않는 인스턴스를 참조한다는 것을 확신할 수 있을 때에만 사용하세요.

만약 우리가 미소유 참조의 값에 접근하려고 시도한다면, 그것도 인스턴스가 할당해제된 후라면, 우리는 런타임 에러를 얻게 될 거에요.

 

 

The following example defines two classes, Customer and CreditCard, which model a bank customer and a possible credit card for that customer. 

These two classes each store an instance of the other class as a property. 

This relationship has the potential to create a strong reference cycle.

 

다음의 예시는 두 클래스를 정의하고 있어요, Customer 와 CreditCard 죠. 은행 고객과 이 고객에게 가능한 신용 카드를 모델링하고 있어요.

이러한 두 클래스는 각각 프로퍼티로 다른 클러스의 인스턴스를 저장하고 있습니다. 이 관계는 잠재적으로 강한 순환 참조를 만들어낼 수 있어요. 


The relationship between Customer and CreditCard is slightly different from the relationship between Apartment and Person seen in the weak reference example above. 

In this data model, a customer may or may not have a credit card, but a credit card will always be associated with a customer. 

CreditCard instance never outlives the Customer that it refers to. 

To represent this, the Customer class has an optional card property, but the CreditCard class has an unowned (and non-optional) customer property.

 

Customer 와 CreditCard 사이의 관계는 전에 약한 참조때 보았던 Apartment 와 Person 사이의 관계와는 약간 달라요.

이 데이터 모델에서는 소비자는 신용카드를 가지고 있을지도, 아닐지도 모르지만, 그러나 신용카드는 항상 소비자와 연관될 거에요.

(+ 신용카드는 소비자가 사용하는 것이지만, 소비자는 신용카드를 안쓰고 체크카드를 쓸 지도 모르잖아요?)  

(+ 앞에서 본 아파트와 사람(세입자)의 관계는 아파트에 사람이 살 수 있지만 없을 수도 있었죠.)

CreditCard 인스턴스는 절대로 자신이 참조하는 Customer 보다 더 오래 지속되지 않아요.

(+ 소비자는 신용이 없어도 존재할 수 있지만 신용카드는 신용이 없으면 발급이 안되기 때문. 정도로 이해하면 좋겠죠?)

이를 나타내기 위해 Customer 클래스는 옵셔널 타입의 card 프로퍼티를 가지지만, CreditCard 클래스는 customer 프로퍼티를 미소유 참조로(옵셔널이 아닌) 가지게 됩니다. 

(+ 위에서 미소유 참조는 자신보다 더 긴 수명을 가지고 있는 인스턴스에 사용한다고 했듯, 신용카드 클래스보다 소비자 클래스가 더 긴 수명을 가지고 있기 때문에 신용카드 내부의 소비자 프로퍼티에 미소유 참조 키워드를 붙였다고 보시면 되겠습니다.)

Furthermore, a new CreditCard instance can only be created by passing a number value and a customer instance to a custom CreditCard initializer. 

This ensures that a CreditCard instance always has a customer instance associated with it when the CreditCard instance is created.

 

더군다나 새 CreditCard 인스턴스는 숫자 값(number value)customer 인스턴스를 커스텀 CreditCard 이니셜라이저에 전달함으로서 오직 생성될 수 있습니다. 이는 CreditCard 인스턴스가 생성 될 때 이 인스턴스에 항상 연결된 customer 인스턴스가 있다는 것을 보장합니다.


Because a credit card will always have a customer, you define its customer property as an unowned reference, to avoid a strong reference cycle:

 

왜냐하면 신용카드는 항상 소비자를 가지고 있을 것이기 때문에(+ 신용카드의 사용 주체는 소비자이죠!),

우리는 customer 프로퍼티를 미소유 참조로서 정의하여 강한 순환 참조를 피합니다:

 

 

NOTE

The number property of the CreditCard class is defined with a type of UInt64 rather than Int

to ensure that the number property’s capacity is large enough to store a 16-digit card number on both 32-bit and 64-bit systems.

 

CreditCard 클래스의 number 프로퍼티는 UInt64 타입으로 정의됩니다. Int 가 아니에요. 이는 number 프로퍼티의 용량이 32비트와 64비트 시스템 상에서 16자리 카드 번호를 저장할 수 있을만큼 충분히 넓도록 하는 것을 보장하기 위함입니다.

 

 

This next code snippet defines an optional Customer variable called john, which will be used to store a reference to a specific customer.

This variable has an initial value of nil, by virtue of being optional:

 

다음의 코드 스니펫은 옵셔널 타입의 Customerjohn 이라는 이름의 변수로 정의했으며, 특정 소비자에 대한 참조를 저장하기 위해 사용 될 것입니다. 이 변수는 초기값 nil 을 가지는데 옵셔널이기 때문입니다.

 

You can now create a Customer instance, and use it to initialize and assign a new CreditCard instance as that customer’s cardproperty:

 

우리는 Customer 인스턴스를 이제 생성할 수 있으며, 이 인스턴스를 새로운 CreditCard 인스턴스를 소비자의 card 프로퍼티로 초기화 및 할당하기 위해 사용해요. 

 

 

Here’s how the references look, now that you’ve linked the two instances:

 

다음은 두 인스턴스를 연결 했으므로 참조가 어떻게 나타나는지 보여줍니다.

 

The Customer instance now has a strong reference to the CreditCard instance, and the CreditCard instance has an unowned reference to the Customer instance.

 

Customer 인스턴스는 이제 CreditCard 인스턴스에 대해 강한 참조를 가지며, CreditCard 인스턴스는 Customer 인스턴스에 대해 미소유 참조를 가집니다.

 

Because of the unowned customer reference, when you break the strong reference held by the john variable,

there are no more strong references to the Customer instance:

 

미소유된 customer 참조 때문에, 우리가 john 변수에 의해 잡혀있던 강한 참조를 깨뜨릴 때, 더 이상의 Customer 인스턴스에 대한 강한 참조는 없습니다.

 

 

Because there are no more strong references to the Customer instance, it’s deallocated.

After this happens, there are no more strong references to the CreditCard instance, and it too is deallocated:

 

왜냐하면 더 이상 Customer 인스턴스에 대한 강한 참조가 없으며, 할당 해제되었기 때문입니다. 이것이 발생한 후에, CreditCard 인스턴스에 대한 강한 참조도 더 이상 없으며 얘도 또한 할당 해제됩니다. 

 

The final code snippet above shows that the deinitializers for the Customer instance and CreditCard instance both print their

“deinitialized” messages after the john variable is set to nil.

 

위의 최종 코드 스니펫은 john 변수에 nil 이 할당된 후, Customer 인스턴스와 CreditCard 인스턴스의 디이니셜라이저가 둘 다 자신의 "diinitialized" 메시지를 출력하는 것을 보여주고 있습니다. 

 

 

NOTE

 

The examples above show how to use safe unowned references. 

Swift also provides unsafe unowned references for cases where you need to disable runtime safety checks

for example, for performance reasons. As with all unsafe operations, you take on the responsibility for checking that code for safety.

 

위의 예시는 안전한 미소유 참조를 사용하는 방법을 보여줍니다. Swift 는 또한 런타임 안전성 검사를 비활성화해야할 필요가 있을 경우엔  안전하지 않은 미소유 참조도 제공합니다. 예를 들어, 퍼포먼스적(= 성능) 이유가 있겠죠. 모든 안전하지 않은 작업과 마찬가지로, 우리는 안전을 위해 코드를 점검해야 할 책임감을 가져야 합니다. 

 

You indicate an unsafe unowned reference by writing unowned(unsafe).

If you try to access an unsafe unowned reference after the instance that it refers to is deallocated,

your program will try to access the memory location where the instance used to be, which is an unsafe operation.

 

안전하지 않은 미소유 참조를 unowned 를 작성함으로써 나타낼 수 있습니다.

만약 참조하고 있는 인스턴스가 할당 해제된 후에 안전하지 않은 미소유 참조에 엑세스를 시도할 경우,

프로그램은 예전의 메모리 위치((안전하지 않은 작업)에 엑세스하려고 시도할 것입니다.

(+ 이 부분 번역이 좀 매끄럽지 못하네요.. 조금 더 알아보도록 하겠습니다.)

 

 

오늘은 여기까지! 전체 코드 첨부합니다.

 

 

 

간만에 작성을 하려니 앞 부분이 생각이 안나서 번역을 다시 살펴보면서 이번 글을 작성했습니다.

쉽지 않네요 역시. 다음에는  '미소유 참조와 암시적 언래핑된 옵셔널 프로퍼티' 에 대해서 알아보겠습니다.

 

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
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
글 보관함