22-3. 약한 참조와 미소유 참조(weak reference, unowned reference)

🌈 devleeky16498·2022년 4월 23일
0

약한 참조(Weak reference)

  1. 약한 참조는 참조하는 인스턴스를 강하게 유지하지 않는 참조이다. 따라서 ARC가 참조된 인스턴스를 처리하는 것을 중지하지 않는다. 이는 프로퍼티 변수 선언 전에 weak 키워드를 위치시켜서 약한 참조를 나타낸다.
  2. 약한 참조는 참조하는 인스턴스를 강하게 유지하지 않으므로 약한 참조 동안 해당 인스턴스가 할당 해제될 수 있다. 따라서 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 is faded")
    }
}
//강한 참조와 다르게 이번에는 Apartment타입의 tenant 프로퍼티는 약한 참조로 선언되었다. 

//아래코드에서 상호 인스턴스간의 강한 참조는 동일하게 생성된다.

var john : Person?
var unit4A : Apartment?
john = person(name : "John")
unit4A = Apartment(unit : "4A")

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

//현재 상황에서 Person 인스턴스는 Apartment에 대한 강한 참조를 가지지만,
//Apartment는 Person에 대한 약한 참조를 가진다.
//이것은 john 변수에 nil을 설정해서 강한 참조를 끊으면 
//Person인스턴스에 대한 Apartment의 참조가 더 이상 강한 참조가 아니다.

john = nil
//Person 인스턴스는 해제되게 된다.
//이에 따라서 Person에 대한 더 이상 강한 참조를 가지지 않고, tenant프로퍼티는 nil이 된다.

unit4A = nil
//다음과 같은 시 Apartment에 대한 강한 참조가 더 이상 없으므로 할당해제 된다.

미소유 참조(Unowned reference)

  1. 약한 참조와 마찬가지로 미소유 참조는 참조하는 인스턴스를 강하게 유지하지 않는다. 그러나 약한 참조와 다르게 미소유 참조는 다른 인스턴스의 수명이 같거나 긴 경우에 사용된다.
  2. 프로퍼티 변수 선언 전 unowned키워드를 위치시켜서 미소유 참조를 나타낸다.
  3. 약한 참조와 다르게 미소유 참조는 항상 값을 가지도록 예상된다. 결과적으로 미소유로 만들어진 값은 옵셔널이 아닌 ARC는 미소유 참조값을 nil로 설정하지 않는다.
  4. 참조가 '항상' 할당해제되지 않은 인스턴스를 참조한다고 확신하는 경우에만 미소유 참조를 사용한다. 인스턴스가 할당 해제된 후 미소유 참조값에 접근하려고 하면 에러가 난다.
class Customer {
	let name : String
    var card : CreditCard?
    init(name : String) {
    	self.name = name
    }
    deinit {
    	print("customer instance is faded")
    }
}

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

//다음과 같이 Creditcard내 Customer는 unowned로서 미소유 참조로 선언한다. 

var john : Customer?
//이제 john에 대한 인스턴스 생성이 가능하며, 해당 고객의 card프로퍼티에 대해
//Creditcard 인스턴스 초기화 할당이 가능하다.

john = Customer(name : "John")
john!.card = CreditCard(number : 123123, customer : john!)
//Customer 인스턴스는 CreditCard에 대한 강한 참조를 가지고 CreditCard는 Customer에 대한 미소유 참조를 가진다.
//john에 의해 강한 참조를 끊을 때 이는 더 이상 강한 참조를 가지지 않으며,
//더 이상 customer 인스턴스에 대한 강한 참조가 아니므로 할당 해제된다.
//CreditCard인스턴스도 이어서 해제된다.

john = nil
//print("customer instance is faded")
//print("Card is deinitialized")
//두개가 한번에 출력된다.
profile
Welcome to Growing iOS developer's Blog! Enjoy!🔥

0개의 댓글