티스토리 뷰

Auto Reference Counting - Part 3

( a.k.a ARC )




Swift 4.2 - The Swift Programming Language (Apple Inc.) 

번역 





5) 클래스의 인스턴스들 간의 강한 순환 참조 해결하기

    (Resolving Strong Reference Cycles Between Class Instances)



Swift provides two ways to resolve strong reference cycles when you work with properties of class type: weak references and unowned references.


Swift 는 여러분들이 클래스 타입의 프로퍼티를 사용하여 작업할 때, 강한 순환 참조를 해결하기 위한 두 가지 방법을 제공합니다. 

첫째. Weak(약한) 참조  / 둘째. unowned(미소유) 참조 


Weak and unowned references enable one instance in a reference cycle to refer to the other instance without keeping a strong hold on it. The instances can then refer to each other without creating a strong reference cycle.


Weak(약한) 와 unowned(미소유) 참조는 어떤 순환 참조 내 하나의 인스턴스가 다른 인스턴스를 강하게 참조하는 것이 없어도 참조 가능하게 만들어 준다. 그 다음, 인스턴스들은 강한 순환 참조를 생성하는 것 없이도 서로가 참조할 수 있게 된다.


Use a weak reference when the other instance has a shorter lifetime—that is, when the other instance can be deallocated first. In the Apartment example above, it’s appropriate for an apartment to be able to have no tenant at some point in its lifetime, and so a weak reference is an appropriate way to break the reference cycle in this case. In contrast, use an unowned reference when the other instance has the same lifetime or a longer lifetime.


다른 인스턴스가 짧은 수명을 가질 땐 weak 참조를 사용하세요(즉, 다른 인스턴스가 먼저 할당 해제될 수 있을 때). 앞선  Part 2 에서 Apartment 의 예시처럼, 아파트의 수명의 어느 시점에선 세입자가 없을 수 있고, 그래서 약한 참조는 이러한 경우에 참조 순환을 깰 수 있는 적절한 방식이다. 대조적으로, 미소유 참조는 다른 인스턴스가 같은 수명 혹은 더 긴 수명을 가질 때 사용한다.


Weak References


weak reference is a reference that does not keep a strong hold on the instance it refers to, and so does not stop ARC from disposing of the referenced instance. This behavior prevents the reference from becoming part of a strong reference cycle. You indicate a weak reference by placing the weak keyword before a property or variable declaration.

약한 참조는 참조하는 인스턴스를 강하게 붙잡고 있는 상태를 유지하지 않는 참조이며, ARC가 참조 된 인스턴스를 삭제하지 않습니다. 이러한 동작은 참조를 강한 순환 참조의 일부가 되는 것을 방지해줍니다. 여러분은 프로퍼티 혹은 변수 선언(var) 전에 weak 키워드를 써줌으로서 약한 참조를 표현하시면 됩니다.


Because a weak reference does not keep a strong hold on the instance it refers to, it’s possible for that instance to be deallocated while the weak reference is still referring to it. Therefore, ARC automatically sets a weak reference to nil when the instance that it refers to is deallocated. And, because weak references need to allow their value to be changed to nil at runtime, they are always declared as variables, rather than constants, of an optional type.

약한 참조는 참조하고 있는 인스턴스에 대해 강하게 붙잡고 있지 않기 떄문에 약한 참조가 여전히 참조 중인 동안에도 인스턴스는 할당 해제되는 것이 가능합니다. 그러므로, ARC는 참조 중인 인스턴스가 할당 해제될 때, 자동적으로 약한 참조에 nil 을 할당하죠. 그리고, 약한 참조가 런타임 중에서도 값이 nil 로 변하도록 허용해야 할 필요가 있기 때문에 약한 참조는 항상 상수가 아닌 옵셔널 타입의 변수로 선언되어야 합니다.


You can check for the existence of a value in the weak reference, just like any other optional value, and you will never end up with a reference to an invalid instance that no longer exists.

여러분은 약한 참조 하에서 값의 존속에 대해 체크해볼 수 있어요, 단지 어느 다른 옵셔널 값처럼요. 그리고 여러분은 더 이상 존재하지 않는 유효하지 않은 인스턴스에 대한 참조를 결코 하지 않게 될 것입니다.  ( + 설명이 어렵다면 밑의 예시를 통해서 이해해보도록 하죠 ! )

( 이 부분 좀 번역이 이상한데 깔끔한 번역 되시는 분! 플리즈 썸바디 헬 미... )


NOTE - Property observers aren't called when ARC sets a weak reference to nil. 

주목 - ARC가 약한 참조에 nil 을 할당할 때, 프로퍼티 옵저버는 호출되지 않습니다.


The example below is identical to the Person and Apartment example from above, with one important difference. This time around, the Apartment type’s tenant property is declared as a weak reference:

아래의 예시는 앞서 살펴본 Person 과 Apartment 예시와 같습니다. 아! 하나의 중요한 차이가 있어요. 이번에는 Apartment 타입의 tenant 프로퍼티가 약한 참조로 선언되어 있어요 :


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") }

}



The strong references from the two variables (john and unit4A) and the links between the two instances are created as before:


두 개의 변수(john & unit4A) 로 부터의 강한 참조와 두 인스턴스의 사이의 연결은 앞선 예처럼 생성되어 있습니다 :



var john: Person?

var unit4A: Apartment?


john = Person(name: "John Appleseed")

unit4A = Apartment(unit: "4A")


john!.apartment = unit4A

unit4A!.tenant = john



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


아래의 그림을 통해 이제 여러분이 연결한 두 인스턴스들의 참조가 어떻게 보여지는지 볼까요?





The Person instance still has a strong reference to the Apartment instance, but the Apartment instance now has a weak reference to the Person instance. This means that when you break the strong reference held by the john variable by setting it to nil, there are no more strong references to the Person instance:


Person 인스턴스는 Apartment 인스턴스에 대해 여전히 강한 참조를 가지고 있군요, 그러나 Apartment 인스턴스는 이제 Person 인스턴스에 대해 약한 참조를 가지게 되었습니다. 이것은 무엇을 의미할까요? 변수 john 에 의해 잡혀있던 강한 참조를 여러분이 변수에 nil 을 할당함으로서 참조를 해제했을 때, Person 인스턴스에 대해서는 더 이상 강한 참조는 없게 됩니다:



john = nil

// Prints "John Appleseed is being deinitialized"



Because there are no more strong references to the Person instance, it’s deallocated and the tenant property is set to nil:


더 이상 Person 인스턴스에 강한 참조가 없기 때문에, 할당 해제되고 tenant 프로퍼티에는 nil 이 할당됩니다. 





The only remaining strong reference to the Apartment instance is from the unit4A variable. If you break that strong reference, there are no more strong references to the Apartment instance:

Apartment 인스턴스에 남아있는 유일한 강한 참조는 unit4A 변수입니다. 만약 여러분이 강한 참조를 해제한다면, 더 이상 Apartment 인스턴스에는 강한 참조가 없게 됩니다. 


unit4A = nil

// Prints "Apartment 4A is being deinitialized"



Because there are no more strong references to the Apartment instance, it too is deallocated:

Apartment 인스턴스에는 더 이상 강한 참조가 없기 때문에, 이 인스턴스도 할당 해제됩니다.




Note !


In systems that use garbage collection, weak pointers are sometimes used to implement a simple caching mechanism because objects with no strong references are deallocated only when memory pressure triggers garbage collection. However, with ARC, values are deallocated as soon as their last strong reference is removed, making weak references unsuitable for such a purpose.



주목 !


가비지 컬렉션을 사용하는 시스템에서는(ex. 자바),  weak 포인터가 때때로 간단한 캐싱 메커니즘을 수행하기 위해 사용되는데 왜냐면 메모리가 가비지 컬렉션을 작동시킬 때만 강한 참조가 없는 객체가 할당 해제되기 때문입니다. 그러나, ARC 하에서 값은 그들의 마지막 강한 참조가 제거되자마자 할당 해제되어 약한 참조를 만드는 것은 그러한 목적에는 부적합합니다.







번역의 오역에 대한 지적 감사드리겠습니다 ! 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
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
글 보관함