티스토리 뷰

반응형

 


Unowned References 미소유 참조

약한참조(weak reference)와 같이, 미소유 참조(unowned reference) 또한 참조하는 인스턴스를 강하게 참조하지 않습니다.(참조할때 weak과 동일하게 RC(Reference Count)를 증가시키지 않습니다.)
 다만 약한 참조와의 차이점은 참조하려는 다른 인스턴스가 본인과 생애주기가 같거나 더 길 경우에 사용됩니다. unowned 키워드를 프로퍼티나 변수 선언부 앞에 놓아 사용할 수 있습니다.

미소유참조(unowned reference)는 항상 값이 있는 것으로 간주합니다.
 그 결과, ARC는 미소유 참조의 값을 nil로 설정하지 않습니다. 이는 미소유 참조의 값이 옵셔널값이 아닌 것(non-optional)으로 정의됨을 의미합니다.

중요 : 아직 메모리에서 해제되지 않은 인스턴스를 참조하는 것을 확신할 때만 미소유 참조를 사용해야 합니다. 만약 미소유 참조 값이 메모리 상에 없는 상태에서 접근할 경우 런타임 에러를 야기할 수 있습니다.



이어지는 예시에서는 각 은행 고객, 고객을 위한 신용카드를 모델링한 Customer, CreditCard 두 개의 클래스가 정의 되어 있습니다. 이 두 클래스들은 각각 프로퍼티로서 서로의 인스턴스를 갖고 있습니다. 이 관계는 강한순환참조가 발생할 잠재력을 갖게 됩니다.

Customer, CreditCard 사이의 관계는 앞서 보았던 Apartment, Person 사이의 관계(weak을 사용한)와 약간 다릅니다. 데이터 모델을 보면, customer는 credit card를 가지고 있거나 가지고 있지 않을 수도 있습니다. 하지만 credit card는 항상 customer과 연결되어 있습니다. 고객이 참조하는 신용카드는 고객이 참조한 수명보다 오래 지속되지 않습니다.

이를 대표하기 위해, Customer 클래스는 optional로 card 프로퍼티를 갖지만, CreditCard 클래스는 unowned(non-optional)로 customer 프로퍼티를 갖습니다.

추가로, 새로운 CreditCard 인스턴스는 자신의 커스텀 생성자의 number, customer 값을 넘겨받아 생성됩니다. 이는 CreditCard 인스턴스가 생성될 때 항상 number, customer와 같은 CreditCard 관련 인스턴스 값을 갖도록 보장해줍니다.

credit card는 항상 customer 인스턴스를 가질 것이므로, 당신은 customer 프로퍼티는 미소유 참조(unowned reference)로서 정의할 수 있고, 이는 강한순환참조를 피할 수 있는 방법 중 하나가 됩니다.

Customer, CreditCard Class Modeling

참고 : CreditCard 클래스의 number 프로퍼티는 Int 대신 UInt64로서 정의됩니다. number 프로퍼티의 값 공간이 32-bit, 64-bit 시스템들 상에서 16자리 카드 number를 충분히 수용가능하도록 보방하기 위함 입니다.


다음 이어지는 코드는 john이라 불리는 john: Customer? 라는 옵셔널 변수를 정의하며, 이는 특정 고객의 참조를 저장하기 위해 사용 됩니다. 이 변수는 옵셔널, nil로 초기화 됩니다.


당신은 이제 Customer 인스턴스를 생성할 수 있으며 초기화 및 CreditCard 인스턴스를 customercard 프로퍼티로서 할당할 수 있습니다.


아래 그림은 현재 Customer, CreditCard 인스턴스의 참조 상황을 보여줍니다.


Customer 인스턴스는 이제 CreditCard 인스턴스에 대한 강한 참조를 갖습니다. 그리고 CreditCard 인스턴스는 Customer 인스턴스에 대한 미소유 참조(unowned reference)를 갖습니다. customer에 대한 미소유참조 때문에 john 변수의 강한참조가 깨질 때, 어떠한 강한참조순환도 발생하지 않습니다. (미소유참조는 약한참조와 동일하게 참조할때 강한참조를 갖지 않기 때문입니다.)


Customer 인스턴스에 대한 강한참조가 더이상 없으므로, Customer 인스턴스는 정상적으로 메모리에서 해제됩니다. 이 후, CreditCard 인스턴스에 대한 강한참조 또한 없게 되며 CreditCard 인스턴스 또한 메모리에서 정상적으로 해제 됩니다.


상기한 마지막 코드는 john변수가 nil로 설정되면 강한참조를 깼을 때, 덩달아 Customer, CreditCard 인스턴스가 둘다 정상적으로 메모리에서 해제되며 정상적으로 소멸자의 출력문구가 나타나는 것을 보여줍니다.

참고 : 앞서 설명한 예시는 미소유 참조(unowned references)를 안전하게 사용하는 방법을 보여주었습니다. Swift에서는 또한 성능상 등의 이유로 런타임 안정성 체크를 비활성화해야 하는 경우 안전하지 않은 참조를 제공합니다. 안전하지 않은 동작들이 있을 때, 개발자는 안전을 위해 코드를 확인할 책임을 갖고 있습니다.

당신은 참조하는 인스턴스가 해제될 때, 안전하지 않은 미소유 참조로서 접근하고자 한다면, unowned(unsafe)를 작성함으로서 안전하지않은 미소유 참조를 가리킬 수 있습니다. 당신의 프로그램은 불안전한 작동방법으로 인스턴스가 사용되던 메모리 위치의 접근 시도를 하게 될 것입니다.

 



unowned 참조를 보면 생애주기 동안 참조할 값이 있어야 한다는 점에서 사용할 때마다 언래핑을 시도하는 암시적 언래핑 (!) 옵셔널 변수가 함께 연관될 수 있을 것 같은데요. 다음 포스팅에서는 unowned 참조와 암시적 언래핑 옵셔널 변수의 활용에 대해서 다뤄보겠습니다. 많은 의견 환영합니다. 감사합니다. ^-^//

 

참고 문서 링크 ▼

Swift Automatic Reference Counting

 

 

반응형
댓글
반응형
최근에 올라온 글
최근에 달린 댓글
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
글 보관함