궁금한 내용을 검색해보세요!
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
서근 개발노트
티스토리에 팔로잉
SWIFT/Grammar

Swift : 고급문법[ARC 메모리 관리4 - 미소유 참조(unowned)]

서근
QUOTE THE DAY

-
Written by SeogunSEOGUN

반응형

본 게시글은 yagom님의 Swift 프로그래밍 3판을 참고하여 작성되었습니다.

 

미소유 참조 

  • 약한 참조와 같이 미소유 참조도 인스턴스의 참조 횟수를 증가시키지 않음
  • 약한 참조와는 다르게 자신이 참조하는 인스턴스가 메모리에서 해제되더라도 스스로 nil을 할당하지 않음. 그렇기 때문에 변수나 프로퍼티는 옵셔널이나 변수가 아니어도 가능함
  • 하지만, 메모리에서 해제된 인스턴스에 접근하려 하면 잘못된 접근으로 런타임 오류가 발생함
  • 따라서 미소유 참조는 참조하는 동안 그 인스턴스가 메모리에서 해제되지 않는다는 확인이 있을 때만 사용
  • 변수 혹은 속성 앞에 unowned 키워드를 사용하여 미소유 참조임을 타나 냄

전 게시글인 약한 참조에서 PersonRoom 관계에서 약한 참조를 적용해 강한 참조 순환 문제를 해결할 수 있었다. 

 

미소유 참조는 어떤 관계에서 사용할 수 있을까?

 

예를 들어 사람과 신용카드의 관계를 들어보자면

  1. 사람은 신용카드를 가질 수 있다.
  2. 하지만 신용카드는 명의자가 반드시 존재해야 한다. 
  3. 명의자와 신용카드는 서로 참조하는 관계이다.
  4. 신용카드는 명의자가 반드시 존재해야 한다는 확신이 있다.

이 예를 코드로 작성해보자

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

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

var seogun: Customer? = Customer(name: "서근") //Customer 참조 횟수 : 1 

if let person: Customer = seogun {
   // CreditCard 인스턴스 참조 횟수 : 1
  person.card = CreditCard(nummer: 1001-2002-3003-4004, customer: 서근)
   // Customer 참조 횟수 : 1 !!!미소유참조 이니까 횟수 증가 안함.
}

Customer은 카드를 소지할 수도, 소지하지 않을 수도 있기 때문에 옵셔널로 정의하고, 카드를 한 번 가진 후 잃어버리면 안되기 때문에 강한 참조를 해야한다.

 

이 두 인스턴스의 관계는 이래와 같다.

 

서근은 Cutomer 인스턴스에 대해 강한 참조를 가졌고, CreditCard 인스턴스에 customer에 대한 미소유 참조인 Customer가 있다.

 

unowned let customer: Customer 

 

var seogunCustomer 인스턴스에 대한 강한 참조를 해제하려면 nil을 할당하면 된다.

seogun = nil 

//Customer과 CreditCard 인스턴스에 대한 강한 참조가 더이상 존재하지 않으므로 디이니셜라이저 출력

//Customer의 참조 횟수 : 0
//CreditCard의 참조 횟수 : 0

//"서근 is being deinitialized!"
//Card No.1001-2002-3003-4004 is being deinitialized!

이렇게 Customer에 대한 강한 참조가 해제되어 Customer 인스턴스에 대해 강한 참조가 더 이상 없기 때문에 CreditCard 인스턴스도 동시에 강한 참조가 사라진다. 그러므로 CustomerCreditCard의 디이니셜이 출력되며 할당 해제된다.

 

 

읽어주셔서 감사합니다 🤟

 

 


잘못된 내용이 있으면 언제든 피드백 부탁드립니다.


서근


위처럼 이미지 와 함께 댓글을 작성할 수 있습니다.